如何在 Go 语言(Golang)中构建 JWT
作者:Lane Wagner –推特账号:@wagslane
Go 语言在后端 Web 开发领域越来越受欢迎,而 JWT 是处理 API 请求身份验证最常用的方法之一。本文将介绍 JWT 的基础知识,以及如何在 Go 中实现安全的身份验证策略!
什么是JWT?
JSON Web Tokens 是一种开放的、行业标准的RFC 7519方法,用于在双方之间安全地表示声明。
简单来说,JWT 是由服务器签名的编码JSON对象,用于验证其真实性。
例如,当用户登录到使用 JWT 加密的网站时,流程大致如下:
- 用户向服务器发送用户名和密码
- 服务器验证用户名和密码是否正确
- 服务器会创建一个如下所示的 JSON 对象(也称为声明):
- {“username”:”wagslane”}
- 服务器对 JSON 对象进行编码和签名,生成 JWT:
- eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IndhZ3NsYW5lIn0.ov6d8XtwQoKUwsYahk9UwH333NICElFSs6ag6pINyPQ
- 用户的 Web 客户端会保存 JWT 以供后续使用。
- 当用户向受保护的端点发出请求时,JWT 会通过 HTTP 标头传递。
- 服务器会检查 JWT 上的签名,以确保该 JWT 最初是由同一服务器创建的。
- 服务器读取声明并允许请求以“wagslane”身份运行。
创建 JWT
我们将使用一个流行的 Go 语言 JSON Web Token 处理库jwt-go。请确保您已将代码克隆到本地:
go get github.com/dgrijalva/jwt-go
为简化起见,我们构建的是一个对称加密方案。这意味着我们假设生成 JWT 的服务器也将是唯一验证这些 JWT 的服务器。
首先,定义一个结构体,用于表示用于识别用户的声明:
type customClaims struct {
Username string `json:"username"`
jwt.StandardClaims
}
jwt.StandardClaims结构体包含一些有用的字段,例如过期时间和颁发者名称。现在我们将为刚刚登录的用户创建一些实际的声明:
claims := customClaims{
Username: username,
StandardClaims: jwt.StandardClaims{
ExpiresAt: 15000,
Issuer: "nameOfWebsiteHere",
},
}
根据声明创建未签名令牌:
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
使用安全的私钥对令牌进行签名。在生产环境中,请确保使用真实的私钥,最好是至少 256 位长度的私钥:
signedToken, err := token.SignedString([]byte("secureSecretText"))
现在可以把签名后的令牌发送回客户端了。
验证 JWT
当客户端向受保护的端点发出请求时,我们可以使用以下步骤验证 JWT 的真实性。
*注:使用 Authorization HTTP 标头是惯例:
Authorization: Bearer {jwt}
收到 JWT 后,使用相同的私钥验证声明并验证签名:
token, err := jwt.ParseWithClaims(
jwtFromHeader,
&customClaims{},
func(token *jwt.Token) (interface{}, error) {
return []byte("secureSecretText"), nil
},
)
如果声明已被篡改,则 err 变量将不为nil。
解析令牌中的声明:
claims, ok := token.Claims.(*customClaims)
if !ok {
return errors.New("Couldn't parse claims")
}
检查令牌是否过期:
if claims.ExpiresAt < time.Now().UTC().Unix() {
return errors.New("JWT is expired")
}
您现在知道已验证用户的用户名了!
username := claims.Username
有关完整示例,请查看软件包的测试。
感谢阅读!
Lane 的推特账号:@wagslane
Dev.to 上的 Lane:wagslane
下载 Qvault:https://qvault.io
文章《如何在 Go (Golang) 中构建 JWT》最初发表于Qvault。
文章来源:https://dev.to/wagslane/how-to-build-jwt-s-in-go-golang-i7c

