1. 安装 JWT 库
在 Go 项目中使用 JWT 需要先安装 JWT 库,可以使用以下命令安装:
go get github.com/dgrijalva/jwt-go
2. 创建 JWT
在 Go 项目中,可以使用 JWT 库的 jwt.NewWithClaims()
方法创建 JWT。例如:
// 秘钥
var jwtSecret = []byte("My-Todolist-JWT")
type Claims struct {
Id uint `json:"id"`
UserName string `json:"user_name"`
jwt.StandardClaims // 标准的声明
}
// 签发用户token 生成jwt 通过生成和验证 JWT 来确保用户的身份信息是有效的
func GenerateToken(id uint, userName string) (string, error) {
nowTime := time.Now()
expireTime := nowTime.Add(24 * time.Hour)
//创建一个我们自己声明的数据
claims := Claims{
Id: id,
UserName: userName,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expireTime.Unix(), //过期时间
Issuer: "zxcvb", //签发人
},
}
//对称加密 它将 JWT 数据与密钥 jwtSecret 结合起来生成签名。
return jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(jwtSecret)
}
-
jwtSecret
:这是用于签名和验证 JWT 的密钥。在实际应用中,应该使用更安全的方法来存储密钥,而不是硬编码在代码中。 -
Claims
结构体:这是 JWT 中的声明,包括用户的 ID、用户名以及标准的 JWT 声明(如过期时间和签发者)。 -
GenerateToken
函数:这个函数用于生成 JWT。它接受用户的 ID 和用户名作为参数,并返回一个签名的 JWT 字符串。JWT 的有效期设置为 24 小时。
func ParseToken(token string) (*Claims, error) {
//验证签名
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return jwtSecret, nil
})
if tokenClaims != nil {
if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
return claims, nil
}
}
return nil, err
}
-
ParseToken
函数:这个函数用于验证 JWT。它接受一个 JWT 字符串作为参数,并返回 JWT 的声明(Claims
结构体)。在这个函数中,它使用jwt.ParseWithClaims
函数来验证 JWT 的签名,并返回声明。 -
以上就是在 Go 项目中使用 JWT 的基本步骤。需要注意的是,在实际应用中,需要更加严格地设置 JWT 的有效期、密钥等参数,以确保安全性。
4. 在项目中的使用
一般地,我们使用token进行鉴权的时候,使用gin中的中间件来对许多需要鉴权的请求进行判断,中间件的具体内容:
func JWTAuthMiddleware() func(c *gin.Context) { return func(c *gin.Context) { //获取到请求头中的token authHeader := c.Request.Header.Get("Authorization") if authHeader == "" { c.JSON(http.StatusOK, &model.ResponseData{ Code: 200, Msg: "访问失败,请登录!", Data: nil, }) c.Abort() return } // 按空格分割 parts := strings.SplitN(authHeader, " ", 2) if !(len(parts) == 2 && parts[0] == "Bearer") { c.JSON(http.StatusOK, &model.ResponseData{ Code: 200, Msg: "访问失败,无效的token,请登录!", Data: nil, }) c.Abort() return } // parts[1]是获取到的tokenString,我们使用之前定义好的解析JWT的函数来解析它 mc, err := util.ParseToken(parts[1]) if err != nil { c.JSON(http.StatusOK, &model.ResponseData{ Code: 200, Msg: "访问失败,无效的token,请登录!", Data: nil, }) c.Abort() return } // 将当前请求的userID信息保存到请求的上下文c上 c.Set("userID", mc.UserID) c.Next() // 后续的处理函数可以用过c.Get("username")来获取当前请求的用户信息 } }