文章摘要
这篇文章介绍了一个名为`ParseWithClaims`的函数,用于解析带有声明的`tokenString`。该函数通过创建并调用解析器来执行解析操作,解析过程包括解码(基于base64)、签名验证以及根据`header`中的`alg`属性获取加密方法(如`sha256`)。核心内容包括:
1. **解析流程**:
- 使用`ParseUnverified`进行初步解析,获取`token`、`parts`及可能的错误。
- 检查指定的校验方法,并验证签名有效性。
- 处理缺失`Keyfunc`的情况,触发特定错误。
2. **错误处理**:
- 若`Keyfunc`未提供,直接返回验证失败错误。
- 处理签名验证失败的情况,触发相应错误。
3. **验证流程**:
- 根据是否启用`SkipClaimsValidation`,验证`Claims`的合法性。
- 进行签名验证,若成功则标记`token`为有效。
总结而言,文章重点描述了`ParseWithClaims`函数在解析带有声明的`tokenString`过程中涉及的关键步骤及其错误处理机制。
func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options …ParserOption) (*Token, error) {
// 创建解析器,
//ParseWithClaims 解析token字符串
return NewParser(options…).ParseWithClaims(tokenString, claims, keyFunc)
}
func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
// 解析字符串,将根据.进行切割,通过base64进行解码,根据header中的alg属性获取加密方法比如sha256
// 返回值token为Token结构体,parts为字符串切割后的数组
token, parts, err :=p.ParseUnverified(tokenString, claims)
if err !=nil {
return token, err
}
// 判断是否指定校验方法
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 {
// 指定方法与token中的方法不一致
return token, NewValidationError(fmt.Sprintf(“signing method %v is invalid”, alg), ValidationErrorSignatureInvalid)
}
}
// 获取key秘钥
var key interface{}
// 判断是否实现keyfunc,就是第三个参数
if keyFunc==nil {
// keyFunc was not provided. short circuiting validation
return token, NewValidationError(“no Keyfunc was provided.”, ValidationErrorUnverifiable)
}
// 调用方法,返回key值
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{}
// 判断是否进行校验,SkipClaimsValidation默认为false 加上!成为true
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
}
}
}
// 进行签名验证
token.Signature=parts[2]
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
}
// 创建解析器,
//ParseWithClaims 解析token字符串
return NewParser(options…).ParseWithClaims(tokenString, claims, keyFunc)
}
func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
// 解析字符串,将根据.进行切割,通过base64进行解码,根据header中的alg属性获取加密方法比如sha256
// 返回值token为Token结构体,parts为字符串切割后的数组
token, parts, err :=p.ParseUnverified(tokenString, claims)
if err !=nil {
return token, err
}
// 判断是否指定校验方法
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 {
// 指定方法与token中的方法不一致
return token, NewValidationError(fmt.Sprintf(“signing method %v is invalid”, alg), ValidationErrorSignatureInvalid)
}
}
// 获取key秘钥
var key interface{}
// 判断是否实现keyfunc,就是第三个参数
if keyFunc==nil {
// keyFunc was not provided. short circuiting validation
return token, NewValidationError(“no Keyfunc was provided.”, ValidationErrorUnverifiable)
}
// 调用方法,返回key值
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{}
// 判断是否进行校验,SkipClaimsValidation默认为false 加上!成为true
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
}
}
}
// 进行签名验证
token.Signature=parts[2]
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
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。