jwt note

作者: robertzhai | 来源:发表于2023-05-29 20:17 被阅读0次

what is jwt

  • Json Web Token
  • 是一个常用语HTTP的客户端和服务端间进行身份认证和鉴权的标准规范,使用JWT可以允许我们在用户和服务器之间传递安全可靠的信息。

Cookie Session Jwt

  • Cookie 存在客户端,后续请求会携带
  • Session 存在服务器端,配合Cookie使用
  • Jwt 存在客户端, 随请求头 Authorization 发给服务端做校验

Authorization: Bearer <token>

JWT Token组成部分

image.png
  • 不要在header和payload中放置敏感信息,除非加密

Do note that for signed tokens this information, though protected against tampering, is readable by anyone. Do not put secret information in the payload or header elements of a JWT unless it is encrypted.

  • header 、payload 通过base64_decode可以解析成明文
  • signature 是sha256算法和密钥加密生成的
  • 服务端验证token的过程是解析token的明文部分header和payload,再做一次签名比对结果和signature是否一致
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

php -r " echo base64_decode('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9');"
输出:
php -r " echo base64_decode('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9');"
{"alg":"HS256","typ":"JWT"}

php -r " echo base64_decode('eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ');"
输出:
{"sub":"1234567890","name":"John Doe","iat":1516239022}

// SignedString creates and returns a complete, signed JWT.
// The token is signed using the SigningMethod specified in the token.
func (t *Token) SignedString(key interface{}) (string, error) {
    var sig, sstr string
    var err error
    if sstr, err = t.SigningString(); err != nil {
        return "", err
    }
    if sig, err = t.Method.Sign(sstr, key); err != nil {
        return "", err
    }
    return strings.Join([]string{sstr, sig}, "."), nil
}

// Sign implements token signing for the SigningMethod.
// Key must be []byte  生成 token中的 signature
func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {
    if keyBytes, ok := key.([]byte); ok {
        if !m.Hash.Available() {
            return "", ErrHashUnavailable
        }

        hasher := hmac.New(m.Hash.New, keyBytes)
        hasher.Write([]byte(signingString))

        return EncodeSegment(hasher.Sum(nil)), nil
    }

    return "", ErrInvalidKeyType
}

// 解析 token
func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
    token, parts, err := p.ParseUnverified(tokenString, claims)
    if err != nil {
        return token, err
    }

    // Verify signing method is in the required set
    if p.ValidMethods != nil {
        var signingMethodValid = false
        var alg = token.Method.Alg()
        for _, m := range p.ValidMethods {
            if m == alg {
                signingMethodValid = true
                break
            }
        }
        if !signingMethodValid {
            // signing method is not in the listed set
            return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid)
        }
    }

    // Lookup key
    var key interface{}
    if keyFunc == nil {
        // keyFunc was not provided.  short circuiting validation
        return token, NewValidationError("no Keyfunc was provided.", ValidationErrorUnverifiable)
    }
    if key, err = keyFunc(token); err != nil {
        // keyFunc returned an error
        if ve, ok := err.(*ValidationError); ok {
            return token, ve
        }
        return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable}
    }

    vErr := &ValidationError{}

    // Validate Claims
    if !p.SkipClaimsValidation {
        if err := token.Claims.Valid(); err != nil {

            // If the Claims Valid returned an error, check if it is a validation error,
            // If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set
            if e, ok := err.(*ValidationError); !ok {
                vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid}
            } else {
                vErr = e
            }
        }
    }

    // Perform validation
    token.Signature = parts[2]
        // 解析完token 重新做一次签名,比对签名是否一致
    if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil {
        vErr.Inner = err
        vErr.Errors |= ValidationErrorSignatureInvalid
    }

    if vErr.valid() {
        token.Valid = true
        return token, nil
    }

    return token, vErr
}


工作原理

image.png image.png
  • token 可以存于浏览器的localStorage

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/localStorage
https://juejin.cn/post/7149380173027573767

why use jwt

  • 无状态和可扩展性
  • 安全: 防止CSRF攻击;token过期重新认证

ref

相关文章

  • JsonWebToken

    JWT (JsonWebToken) JWT官网['https://jwt.io/'] JWT简介 1.JWT(J...

  • JWT介绍和使用

    最权威网址 JWT官网: https://jwt.io/ 什么是JWT Json web token (JWT),...

  • JWT实现token验证

    JWT官网:https://jwt.io/[https://jwt.io/] JWT(Java版)的github地...

  • 使用RSA公私钥实现JWT令牌的签名和验签

    使用RSA公私钥实现JWT令牌的签名和验签 1、什么是JWT令牌 JWT基本概念可从JWT[https://jwt...

  • JWT Spring-security

    JWT设计原理 JWT结合spring-security在项目中的应用 JWT[https://jwt.io/in...

  • JWT的介绍解析

    JWT的介绍解析 一、什么是JWT?了解JWT,认知JWT 首先jwt其实是三个英语单词JSON Web Toke...

  • JWT、SWT、SAML

    一、 JWT from:https://jwt.io/introduction[https://jwt.io/in...

  • jwt 在微服务中应用

    jwt token jwt 在api 方式中表中的token生成,验证以及获取jwt解密后携带的用户信息 jwt ...

  • FusionAuth JWT

    本文介绍基于 FusionAuth JWT 的 JWT 实现方法。 目录 FusionAuth JWT 简介 代码...

  • .Net Core接入JWT

    JWT网站:https://jwt.io/ JWT基础内容:https://baijiahao.baidu.com...

网友评论

      本文标题:jwt note

      本文链接:https://www.haomeiwen.com/subject/axxsedtx.html