github.com/golang-jwt/jwt包判断传入token加密方式的思考
程序员成长之旅 · 程序员成长之旅/Go语言学习/笔记 · 455 字
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以外还支持以下加密方法
The HMAC signing method (
HS256,HS384,HS512) expect[]bytevalues for signing and validationThe RSA signing method (
RS256,RS384,RS512) expect*rsa.PrivateKeyfor signing and*rsa.PublicKeyfor validationThe ECDSA signing method (
ES256,ES384,ES512) expect*ecdsa.PrivateKeyfor signing and*ecdsa.PublicKeyfor validationThe EdDSA signing method (
Ed25519) expected25519.PrivateKeyfor signing anded25519.PublicKeyfor validation