Go在后端Web开发中变得非常流行,而JWT是处理API请求身份验证的最流行方法之一。 在本文中,我们将介绍JWT的基础知识以及如何在Go!中实现安全的身份验证策略。
什么是JWT?
JSON Web令牌是一种开放的行业标准RFC 7519方法,用于在双方之间安全地表示声明。
简而言之,JWT是已编码的JSON对象,已由服务器签名,以验证真实性。
例如,当用户登录通过JWT保护的网站时,流程应如下所示:
- 用户向服务器发送用户名和密码
- 服务器验证用户名和密码正确
- 服务器创建一个如下所示的JSON对象(也称为声明):
{"username":"wagslane"}
- 服务器对JSON对象进行编码和签名,从而创建JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IndhZ3NsYW5lIn0.ov6d8XtwQoKUwsYahk9UwH333NICElFSs6ag6pINyPQ
- 用户的Web客户端保存JWT供以后使用
- 当用户向受保护的端点发出请求时,它会在HTTP标头中传递JWT
- 服务器检查JWT上的签名,以确保JWT最初是由同一服务器创建的
- 服务器读取索赔,并允许该请求以“
wagslane
”的身份运行
创建一个JWT
我们将在Go, jwt-go中使用一个流行的库来处理JSON Web令牌。 确保您已在本地克隆代码:
go get github.com/dgrijalva/jwt-go
为简单起见,我们正在建立对称加密方案。 这意味着我们假设创建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
![](https://i-blog.csdnimg.cn/blog_migrate/dd70e30301912c4f6f6c0aadde646331.png)
当客户端向受保护的端点发出请求时,我们可以使用以下步骤来验证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 Wagner)
先前发布在https://qvault.io/2020/02/20/how-to-build-jwts-in-go-golang/
From: https://hackernoon.com/how-to-build-jwts-in-go-cf8o374x