让我为你讲解一下“Go语言如何使用golang-jwt/jwt/v4进行JWT鉴权详解”这个完整攻略。
一、什么是JWT鉴权?
JWT(JSON Web Token)是一种基于JSON和Base64编码的轻量级Web认证机制,广泛用于网络应用的身份验证和授权。在JWT鉴权中,用户在登录时请求服务器生成一个JWT Token,并将其保存在客户端。每次用户请求需要鉴权的资源时,客户端将该Token以HTTP Header Authorization的方式发送给服务器,服务器在接收到该Token后,鉴别其内容,并判断是否有权限进行访问。
二、golang-jwt/jwt/v4包介绍
golang-jwt/jwt/v4是一个golang的JWT包,支持生成/验证JWT Token
三、使用golang-jwt/jwt/v4包进行JWT鉴权方法详解
- 导入golang-jwt/jwt/v4包
在需要使用JWT鉴权的地方,首先需要导入golang-jwt/jwt/v4包。
import (
"github.com/golang-jwt/jwt/v4"
)
- 生成JWT Token
在用户登录成功后,需要生成一个JWT Token,生成Token的方式可以使用golang-jwt/jwt/v4包提供的jwt.New方法,示例代码如下:
token := jwt.New(jwt.SigningMethodHS256)
claims := make(jwt.MapClaims)
claims["username"] = "user"
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
token.Claims = claims
tokenString, err := token.SignedString([]byte("secret"))
在上面的代码中,使用jwt.New方法创建一个新的Token,指定Token签名算法为HS256,使用make创建一个MapClaims对象,通过该对象将一些自定义的信息存储在Token中,如上例中存储了用户名"user"和该Token的过期时间。
最后,通过调用SignString方法,将签名好的Token转成字符串,用于之后的存储和传递。
- 验证JWT Token
在客户端向服务端请求需要鉴权的资源时,需要将Token以HTTP Header Authorization的方式发送给服务器。当服务端收到Token后,需要进行解析和验证。
使用golang-jwt/jwt/v4包对Token进行验证的主要方法是jwt.Parse方法,示例代码如下:
tokenString := "xxxxx"
parsedToken, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte("secret"), nil
})
if parsedToken.Valid {
// Token验证成功,进行资源访问操作
} else if validationError, ok := err.(*jwt.ValidationError); ok {
if validationError.Errors&jwt.ValidationErrorExpired != 0 {
// Token已过期
return
}
// Token无效
return
} else {
// Token解析失败
return
}
在上面的代码中,使用jwt.Parse方法解析Token,并使用第二个参数方法对Token进行验证和解析。在示例中,验证使用的签名算法为HS256,通过传入“secret”字串作为秘钥,完成Signature验算。如果Token验证成功,则返回的ParseResult中的Valid字段为true。
如果Token已过期,会抛出ValidationErrorExpired错误,此时需要进行相应操作,如提示用户Token已过期。
如果Token无效,则抛出其它类型的ValidationError错误。
四、使用golang-jwt/jwt/v4包进行JWT鉴权示例
下面给出两个示例,以便更好地理解golang-jwt/jwt/v4包在JWT鉴权中的使用方法。
- 用户登录
用户登录时,需要验证请求中传入的用户名和密码是否正确,如果正确则生成Token并返回给客户端,示例代码如下:
func userLogin(w http.ResponseWriter, r *http.Request) {
// 获取用户名和密码
username := r.FormValue("username")
password := r.FormValue("password")
// TODO: 验证用户名和密码是否正确
// 生成Token
token := jwt.New(jwt.SigningMethodHS256)
claims := make(jwt.MapClaims)
claims["username"] = username
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
token.Claims = claims
tokenString, err := token.SignedString([]byte("secret"))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Token生成失败"))
return
}
// 将Token返回客户端
w.WriteHeader(http.StatusOK)
w.Write([]byte(tokenString))
}
在该示例中,首先获取请求中的用户名和密码,并验证其是否正确(验证代码略),如果正确,则使用jwt.New创建一个新的Token,并将用户名和过期时间以MapClaims的形式存储在Token中。最后,通过调用SignString方法,将签名好的Token转成字符串并返回给客户端。
- 需要鉴权的资源访问
客户端在请求需要鉴权的资源时,需要将Token以HTTP Header Authorization的方式发送给服务器。当服务端接收到请求后,需要对Token进行解析和验证,示例代码如下:
func getResource(w http.ResponseWriter, r *http.Request) {
// 获取Authorization HTTP头
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("请提供Token"))
return
}
// 获取Token
tokenString := authHeader[len("Bearer "):]
// 解析和验证Token
parsedToken, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte("secret"), nil
})
if validationError, ok := err.(*jwt.ValidationError); ok {
if validationError.Errors&jwt.ValidationErrorExpired != 0 {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Token已过期"))
return
}
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("无效Token"))
return
}
if !parsedToken.Valid {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("无效Token"))
return
}
// Token验证成功,进行资源访问操作
w.WriteHeader(http.StatusOK)
w.Write([]byte("这是需要鉴权的资源"))
}
在该示例中,首先获取HTTP Header Authorization中的Token,并解析和验证Token。如果Token验证通过,则进行资源访问操作,如返回资源内容。如果Token无效,则返回相应的HTTP错误码和提示信息。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Go语言如何使用golang-jwt/jwt/v4进行JWT鉴权详解 - Python技术站