📦 归档笔记 — 原创建于 WizNote,仅作归档展示;观点以当年为准,非最新。

github.com/golang-jwt/jwt包判断传入token加密方式的思考

创建时间2022-03-27最后修改2022-03-27原位置/程序员成长之旅/Go语言学习/笔记/字数455
目录:程序员成长之旅/Go语言学习/笔记

github.com/golang-jwt/jwt包判断传入token加密方式的思考


func parseJwt(tokenString string) {

token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {

// 这句话的意思是断言token的加密方法是否为HMAC(即HS256,HS384,HS512)

// 看起来非常魔法, 怎么做到的?

if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {

return nil, fmt.Errorf("Unexpected signing method: %v", t.Header["alg"])

}

return hmacSampleSecret, nil

})

}

深入后发现如下代码


if p.ValidMethods != nil {

var signingMethodValid = false

var alg = token.Method.Alg()

for _, m := range p.ValidMethods {// 将token的加密方法和包支持的加密方式遍历

if m == alg {

signingMethodValid = true

break

}

}

if !signingMethodValid {

// 加密方法不在包支持的加密方法内则返回错误

return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid)

}

}

通过深入jwt.Parse发现, 其实内部原理是先解析token提取Header中的alg值, 最后将这个值和github.com/golang-jwt/jwt这个包支持的加密方法进行逐一比较, 如果alg的值和支持的加密方法匹配则将这个加密方法写入Method

也就是说执行到jwt.Parse第二个参数(我们传入的函数)时, 已经确认传入的token的加密方法是这个包所支持的

随后我们将t.Method进行断言, 确认token使用的加密方式是我们所使用的

这个包除了支持HMAC以外还支持以下加密方法

  1. The HMAC signing method (HS256,HS384,HS512) expect []byte values for signing and validation

  2. The RSA signing method (RS256,RS384,RS512) expect *rsa.PrivateKey for signing and *rsa.PublicKey for validation

  3. The ECDSA signing method (ES256,ES384,ES512) expect *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for validation

  4. The EdDSA signing method (Ed25519) expect ed25519.PrivateKey for signing and ed25519.PublicKey for validation