乐闻世界logo
搜索文章和话题

如何在Go中用JWK验证JWT签名?

1 个月前提问
24 天前修改
浏览次数3

1个答案

1

在Go语言中,使用JWK(JSON Web Keys)来验证JWT(JSON Web Tokens)的签名是一个涉及几个步骤的过程。以下是详细的步骤和示例,说明如何在Go中实现这一功能。

步骤 1: 导入必要的包

首先,您需要导入处理JWT和JWK所需的包。github.com/dgrijalva/jwt-go是处理JWT的流行库,而github.com/lestrrat-go/jwx库可以用来处理JWK。

go
import ( "github.com/dgrijalva/jwt-go" "github.com/lestrrat-go/jwx/jwk" )

步骤 2: 从URL加载JWK

通常,JWK集合可以通过一个公开的URL获得。您可以使用jwk.Fetch函数来从URL加载JWK集合。

go
url := "https://example.com/.well-known/jwks.json" set, err := jwk.Fetch(url) if err != nil { // 处理错误 }

步骤 3: 解析JWT并提取其头部

在验证签名之前,需要解析JWT以提取其头部,特别是kid(Key ID)属性,这对于从JWK集合中选择正确的密钥是必要的。

go
tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" token, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { // 不验证签名 return nil, nil }) if token == nil { // 处理错误 } // 获取kid kid := token.Header["kid"].(string)

步骤 4: 根据kid选择正确的JWK

使用从JWT头部得到的kid来从JWK集合中选择正确的密钥。

go
keys := set.LookupKeyID(kid) if len(keys) == 0 { // 处理错误,没有找到对应的key return } var key interface{} if err := keys[0].Raw(&key); err != nil { // 处理错误 return }

步骤 5: 验证JWT签名

最后,使用从JWK集合中得到的密钥来验证JWT的签名。

go
token, err = jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { return key, nil }) if err != nil { // 处理错误,比如签名不匹配 return } if !token.Valid { // Token无效 return }

完整的例子

将上述步骤整合到一个函数中,可以创建一个验证JWT签名的完整应用。

go
func verifyJWT(tokenString string, jwksUrl string) (bool, error) { set, err := jwk.Fetch(jwksUrl) if err != nil { return false, err } token, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { kid := token.Header["kid"].(string) keys := set.LookupKeyID(kid) if len(keys) == 0 { return nil, fmt.Errorf("no key found for kid: %s", kid) } var key interface{} if err := keys[0].Raw(&key); err != nil { return nil, err } return key, nil }) if err != nil { return false, err } return token.Valid, nil }

这个函数封装了从JWK集合中加载密钥、解析JWT、验证签名等过程。您可以通过改变tokenStringjwksUrl的值来针对不同的场景进行测试。

2024年8月16日 00:11 回复

你的答案