jwt note

2023-05-29  本文已影响0人  robertzhai

what is jwt

Cookie Session Jwt

Authorization: Bearer <token>

JWT Token组成部分

image.png

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.

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

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

why use jwt

ref

上一篇 下一篇

猜你喜欢

热点阅读