Golang Jwt集成
Jwt
Github: https://github.com/golang-jwt/jwt
文档:https://pkg.go.dev/github.com/golang-jwt/jwt
拉取仓库
go get https://github.com/golang-jwt/jwt
代码编写
配置文件
jwt:
key: "WXlqEk8BJXmAjtp" // 随机生成
定义 Payload 结构体 和 逻辑代码
request.go
package jwtauth
import (
"errors"
"github.com/golang-jwt/jwt"
"go.uber.org/zap"
"micro-shop-api/user-web/global"
"time"
)
// CustomClaims 自定义 Payload 信息
type CustomClaims struct {
Id uint // 用户id
Mobile string // 手机号
Nickname string // 用户昵称
jwt.StandardClaims
}
func NewCustomClaimsDefault(id uint, mobile string, nickname string) *CustomClaims {
beforeTime := time.Now().Unix()
return &CustomClaims{
Id: id,
Mobile: mobile,
Nickname: nickname,
StandardClaims: jwt.StandardClaims{
NotBefore: beforeTime, // 生效时间
ExpiresAt: beforeTime + 60*60*24, // 失效时间
Issuer: "lzscxb", // 机构
},
}
}
type JWT struct {
singKey []byte // Jwt 密钥
}
var (
TokenExpired = errors.New("Token is expired") // 令牌过期
TokenNotValidYet = errors.New("Token not active yet") // 令牌未生效
TokenMalformed = errors.New("that's not even a token") // 令牌不完整
TokenInvalid = errors.New("") // 无效令牌
)
// NewJWT 返回一个JWT 实例
func NewJWT() *JWT {
return &JWT{
singKey: []byte(global.Config.JwtInfo.SingKey),
}
}
// CreateToken 创建新的 Token
func (j *JWT) CreateToken(claims CustomClaims) (token string, err error) {
withClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return withClaims.SignedString(j.singKey)
}
// ParseToken 验证 Token
func (j *JWT) ParseToken(token string) (*CustomClaims, error) {
withClaims, err := jwt.ParseWithClaims(token, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return j.singKey, nil
})
if err != nil {
// 获取到 Jwt ValidationError 错误类型
if ve, ok := err.(*jwt.ValidationError); ok {
zap.S().Infof("获取到 Jwt ValidationError 原:%v 错误类型:%v", err, ve.Errors)
if ve.Errors&jwt.ValidationErrorMalformed != 0 { // 令牌不完整
return nil, TokenMalformed
} else if ve.Errors&jwt.ValidationErrorExpired != 0 { // 令牌过期
return nil, TokenExpired
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 { // 令牌还未生效
return nil, TokenNotValidYet
} else {
return nil, TokenInvalid
}
}
return nil, TokenInvalid
}
if withClaims == nil {
return nil, TokenInvalid
}
if claims, ok := withClaims.Claims.(*CustomClaims); ok { // 验证成功
return claims, nil
}
return nil, TokenInvalid
}
示例
生成 Token
j := jwtauth.NewJWT()
claims := jwtauth.NewCustomClaimsDefault(uint(id),mobile, nickname)
token, err := j.CreateToken(*claims)
if err != nil {
return
}
fmt.Println(token)
中间件验证 Token
func JwtAuth() gin.HandlerFunc {
return func(c *gin.Context) {
// 获取 header 中的 token
token := c.GetHeader("Authorization")
j := jwtauth.NewJWT()
// 验证 token
claims, err := j.ParseToken(token)
if err != nil {
// 验证失败
c.Abort() // 中断,中间件中 return 不生效
}
c.Set("uid", claims.Id)
c.Set("mobile", claims.Mobile)
c.Next()
}
}
使用中间件
UserRoute := router.Group("user").Use(middleware.JwtAuth())