[英]How to decode a JWT token in Go?
我目前正在处理 Go 应用程序。 我从客户端收到一个 JWT 令牌,我需要解码该令牌并获取相关信息:用户、姓名等。
我正在检查可用于处理 JWT 令牌的库,然后我来到了dgrijalva/jwt-go
,但我不知道如何以简单的方式实现我的目标。
我有令牌,我需要将信息解码为 map 或至少为 json。我该怎么做?
我目前正在开发一个 Golang 应用程序。我从客户端收到一个 JWT 令牌,在 Go 中我需要解码该令牌并获取信息:用户、名称等。我正在检查可用于处理 JWT 的库令牌,我归结为https://github.com/dgrijalva/jwt-go ,但我不知道如何简单地制作我需要的东西。
我有令牌,我需要将信息解码成地图或至少是 json。 我在哪里可以找到如何操作的指南? 谢谢!
我目前正在开发一个 Golang 应用程序。我从客户端收到一个 JWT 令牌,在 Go 中我需要解码该令牌并获取信息:用户、名称等。我正在检查可用于处理 JWT 的库令牌,我归结为https://github.com/dgrijalva/jwt-go ,但我不知道如何简单地制作我需要的东西。
我有令牌,我需要将信息解码成地图或至少是 json。 我在哪里可以找到如何操作的指南? 谢谢!
由于问题和答案都提到了 JWT 库github.com/dgrijalva/jwt-go
,请注意这个库已经很久没有维护了。
截至 2021 年 6 月,社区分叉golang-jwt/jwt由原作者 Dave Grijalva 正式加持。
这也意味着库导入路径发生了变化。 请注意,
当前
主要版本v3
不在 Go 模块上,因此您仍会在go.mod
中看到v3.x.x+incompatible
。
编辑:自 2021 年 8 月起, golang-jwt/jwt
的v4
版本可用。 这终于支持 Go modules 了。 新版本向后兼容以前的版本,因此为了迁移只需将旧的导入路径替换为:
github.com/golang-jwt/jwt/v4
然后根据需要更新您的模块 - 另请参阅 迁移指南了解详细信息。
最值得注意的是,fork 修复了原始库的一个重要安全问题。 在修复之前,该库没有正确处理 JWT 声明中的多个aud
,使其实际上不符合 JWT 规范。
除此之外,主要的 API 还是一样的。 例如,使用 HMAC 验证解析 JWT:
tokenString := /* raw JWT string*/
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, errors.New("unexpected signing method")
}
return []byte(/* your JWT secret*/), nil
})
if err != nil {
// handle err
}
// validate the essential claims
if !token.Valid {
// handle invalid tokebn
}
要使用自定义声明解析 JWT,您可以定义自己的结构类型并将jwt.StandardClaims
嵌入其中:
type MyClaims struct {
jwt.StandardClaims
MyField string `json:"my_field"`
}
tokenString := /* raw JWT string*/
// pass your custom claims to the parser function
token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, errors.New("unexpected signing method")
}
return []byte(/* your JWT secret*/), nil
})
// type-assert `Claims` into a variable of the appropriate type
myClaims := token.Claims.(*MyClaims)
该库的一个有效替代方案是lestrrat-go/jwx
。 API 略有不同,但也非常易于使用:
tokenString := /* raw JWT string*/
// parse and verify signature
tok, err := jwt.Parse(tokenString, jwt.WithVerify(jwa.HS256, []byte(/* your JWT secret */)))
if err != nil {
// handle err
}
// validate the essential claims
if err := jwt.Validate(tok); err != nil {
// handle err
}
我目前正在开发一个 Golang 应用程序。我从客户端收到一个 JWT 令牌,在 Go 中我需要解码该令牌并获取信息:用户、名称等。我正在检查可用于处理 JWT 的库令牌,我归结为https://github.com/dgrijalva/jwt-go ,但我不知道如何简单地制作我需要的东西。
我有令牌,我需要将信息解码成地图或至少是 json。 我在哪里可以找到如何操作的指南? 谢谢!
我目前正在开发一个 Golang 应用程序。我从客户端收到一个 JWT 令牌,在 Go 中我需要解码该令牌并获取信息:用户、名称等。我正在检查可用于处理 JWT 的库令牌,我归结为https://github.com/dgrijalva/jwt-go ,但我不知道如何简单地制作我需要的东西。
我有令牌,我需要将信息解码成地图或至少是 json。 我在哪里可以找到如何操作的指南? 谢谢!
我有一种非常相似的用例,我想在解码后验证访问令牌并从中提取字段(例如: iss
、 sub
、 aud
、 exp
、 iat
、 jti
等)。 对于我的用例,我使用了 jwx和jwt-go库。
请在此处找到对我有用的详细代码片段。
module my-go-module
go 1.16
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/lestrrat-go/jwx v1.0.4
)
package main
import (
"errors"
"fmt"
"github.com/dgrijalva/jwt-go"
"github.com/lestrrat-go/jwx/jwa"
"github.com/lestrrat-go/jwx/jwk"
)
func main() {
jwksURL := "https://your-tenant.auth0.com/.well-known/jwks.json"
keySet, _ := jwk.Fetch(jwksURL)
var accessToken = "eyJhbGciOiJSUzI1NiIsImtpZCI6Ind5TXdLNEE2Q0w5UXcxMXVvZlZleVExMTlYeVgteHlreW1ra1h5Z1o1T00ifQ.eyJzdWIiOiIwMHUxOGVlaHUzNDlhUzJ5WDFkOCIsIm5hbWUiOiJva3RhcHJveHkgb2t0YXByb3h5IiwidmVyIjoxLCJpc3MiOiJodHRwczovL2NvbXBhbnl4Lm9rdGEuY29tIiwiYXVkIjoidlpWNkNwOHJuNWx4ck45YVo2ODgiLCJpYXQiOjE0ODEzODg0NTMsImV4cCI6MTQ4MTM5MjA1MywianRpIjoiSUQuWm9QdVdIR3IxNkR6a3RUbEdXMFI4b1lRaUhnVWg0aUotTHo3Z3BGcGItUSIsImFtciI6WyJwd2QiXSwiaWRwIjoiMDBveTc0YzBnd0hOWE1SSkJGUkkiLCJub25jZSI6Im4tMFM2X1d6QTJNaiIsInByZWZlcnJlZF91c2VybmFtZSI6Im9rdGFwcm94eUBva3RhLmNvbSIsImF1dGhfdGltZSI6MTQ4MTM4ODQ0MywiYXRfaGFzaCI6Im1YWlQtZjJJczhOQklIcV9CeE1ISFEifQ.OtVyCK0sE6Cuclg9VMD2AwLhqEyq2nv3a1bfxlzeS-bdu9KtYxcPSxJ6vxMcSSbMIIq9eEz9JFMU80zqgDPHBCjlOsC5SIPz7mm1Z3gCwq4zsFJ-2NIzYxA3p161ZRsPv_3bUyg9B_DPFyBoihgwWm6yrvrb4rmHXrDkjxpxCLPp3OeIpc_kb2t8r5HEQ5UBZPrsiScvuoVW13YwWpze59qBl_84n9xdmQ5pS7DklzkAVgqJT_NWBlb5uo6eW26HtJwHzss7xOIdQtcOtC1Gj3O82a55VJSQnsEEBeqG1ESb5Haq_hJgxYQnBssKydPCIxdZiye-0Ll9L8wWwpzwig"
token, err := verify(accessToken, keySet)
if err != nil {
fmt.Printf("Gor an error while verifiying access token: %v\n", err)
}
// Check if the token is valid.
if !token.Valid {
fmt.Println("The token is not valid.")
}
// Extract key value from the token and print them on console
claims := token.Claims.(jwt.MapClaims)
for key, value := range claims {
fmt.Printf("%s\t%v\n", key, value)
}
}
func verify(tokenString string, keySet *jwk.Set) (*jwt.Token, error) {
tkn, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if token.Method.Alg() != jwa.RS256.String() {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
kid, ok := token.Header["kid"].(string)
if !ok {
return nil, errors.New("kid header not found")
}
keys := keySet.LookupKeyID(kid)
if len(keys) == 0 {
return nil, fmt.Errorf("key %v not found", kid)
}
var raw interface{}
return raw, keys[0].Raw(&raw)
})
return tkn, err
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.