一、获取jwt项目仓库
go get github.com/golang-jwt/jwt
二、编写jwt token 产生和解析
// tokens
package models
import (
"errors"
"mygo2/conf"
"time"
"github.com/golang-jwt/jwt"
)
const (
TokenTypeUser = "user"
UserIdTokenKey = "uid"
)
//定义错误信息
var ErrInvalidToken = errors.New("invalid token")
var ErrInvalidType = errors.New("invalid token type")
var ErrInvalidID = errors.New("invalid id")
type TokenClaims struct {
jwt.StandardClaims
Type string `json:"typ,omitempty"`
UserID int64 `json:"uid,omitempty"`
}
//产生token
func NewToken(tType string, id interface{}) (string, error) {
secret := conf.Config.JWTSecret
claims := &TokenClaims{
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Unix() + int64(2), //token过期时间,这里测试配置2秒
},
Type: tType,
}
if tType == TokenTypeUser {
if tID, ok := id.(int64); ok && tID > 0 {
claims.UserID = tID
} else {
return "", ErrInvalidID
}
} else {
return "", ErrInvalidType
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(secret))
}
//解析token
func ParseToken(tokenString string) (*TokenClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &TokenClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(conf.Config.JWTSecret), nil
})
if err == nil && token.Valid {
return token.Claims.(*TokenClaims), nil
} else if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
return nil, ErrInvalidToken
} else {
return nil, ErrInvalidToken
}
} else {
return nil, ErrInvalidToken
}
}
三、验证
生产token测试
//生产token
var a int64 = 2
token, err := models.NewToken("user", a)
if err != nil {
panic(err)
}
fmt.Println("token:", token)
//打印结果: token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NzE3ODYxODQsInR5cCI6InVzZXIiLCJ1aWQiOjJ9.WWAGaZLBVsOb7xRRLsb4JFJhEngRTcoDKVzA72K0kkE
无效token
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NzE3ODU0OTMsInR5cCI6InVzZXIiLCJ1aWQiOjJ9.Qw5fY74_nB8JWbStBOzqFuRsbRDR5ngNJnjgCdXtdgA"
tc, err2 := models.ParseToken(token)
if err2 != nil {
fmt.Print(err2)
//打印结果:invalid token
}
fmt.Printf("%+v", tc)
有效token
tc, err2 := models.ParseToken(token)
if err2 != nil {
fmt.Print(err2)
}
fmt.Printf("%+v", tc)
//打印结果,获取到type和UserID: &{StandardClaims:{Audience: ExpiresAt:1671786428 Id: IssuedAt:0 Issuer: NotBefore:0 Subject:} Type:user UserID:2}