JWT.GO
package jwt
import (
“errors”
“fmt”
“time”
“github.com/beego/beego/v2/adapter/logs”
“github.com/beego/beego/v2/client/orm”
beego “github.com/beego/beego/v2/server/web”
context “github.com/beego/beego/v2/server/web/context”
“github.com/dgrijalva/jwt-go”
)
// JwtAuth 中间件,检查token
func JwtAuth(next beego.FilterFunc) beego.FilterFunc {
return func(ctx *context.Context) {
token := ctx.Request.Header.Get(“X-Token”)
if token == “” {
OutJson(ctx, utils.ResultJson{Code: 401, Msg: “无权访问”})
return
}
Jwt := NewJWT()
claims, err := Jwt.ParseToken(token)
if err != nil {
if err == TokenExpired {
OutJson(ctx, utils.ResultJson{Code: -1, Msg: “授权已过期”})
} else {
OutJson(ctx, utils.ResultJson{Code: -1, Msg: “非法的授权”})
}
return
}
ctx.Input.SetData(“admin_token_claims”, claims)
// 这里写你的权限逻辑
}
}
// 这是权限输出给权限的
func OutJson(ctx *context.Context, OutData utils.ResultJson) {
ctx.Output.Status = 200
ctx.Output.Header(“Access-Control-Allow-Credentials”, “true”)
ctx.Output.Header(“Access-Control-Allow-Headers”, “x-token,X-Token”)
ctx.Output.Header(“Access-Control-Allow-Methods”, “GET,POST,PUT,DELETE,OPTIONS”)
ctx.Output.Header(“Access-Control-Allow-Origin”, “*”)
ctx.Output.Header(“Access-Control-Expose-Headers”, “Content-Length,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Content-Type”)
ctx.Output.JSON(OutData, true, true)
}
// JWT 签名结构
type JWT struct {
SigningKey []byte
}
// 一些常量
var (
TokenExpired error = errors.New(“Token is expired”)
TokenNotValidYet error = errors.New(“Token not active yet”)
TokenMalformed error = errors.New(“That’s not even a token”)
TokenInvalid error = errors.New(“Couldn’t handle this token:”)
SignKey string = “www.bugquit.com”
)
// 载荷,可以加一些自己需要的信息
type CustomClaims struct {
ID int `json:”id”` //这个是你自定义的数据
AdminInfo interface{} `json:”admin_info”`//这个是你自定义的数据
jwt.StandardClaims
}
// 新建一个jwt实例
func NewJWT() *JWT {
return &JWT{
[]byte(GetSignKey()),
}
}
// 获取signKey
func GetSignKey() string {
return SignKey
}
// 这是SignKey
func SetSignKey(key string) string {
SignKey = key
return SignKey
}
// CreateToken 生成一个token
func (j *JWT) CreateToken(claims CustomClaims) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(j.SigningKey)
}
// 解析Tokne
func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return j.SigningKey, nil
})
if err != nil {
if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
return nil, TokenMalformed
} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
// Token is expired
return nil, TokenExpired
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
return nil, TokenNotValidYet
} else {
return nil, TokenInvalid
}
}
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
return claims, nil
}
return nil, TokenInvalid
}
// 更新token
func (j *JWT) RefreshToken(tokenString string) (string, error) {
jwt.TimeFunc = func() time.Time {
return time.Unix(0, 0)
}
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return j.SigningKey, nil
})
if err != nil {
return “”, err
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
jwt.TimeFunc = time.Now
claims.StandardClaims.ExpiresAt = time.Now().Add(1 * time.Hour).Unix()
return j.CreateToken(*claims)
}
return “”, TokenInvalid
}
使用路由过滤器实现
beego.InsertFilterChain(“/admin/api/v1/*”, jwt.JwtAuth) //这里设置鉴权
签发,在登录时
Claims := jwt_admin.CustomClaims{
AdminInfo.Id,//这个是你自定义的数据,对应JWT里面的
AdminInfo,//这个是你自定义的数据,对应JWT里面的
jwtgo.StandardClaims{
NotBefore: int64(time.Now().Unix()), // 签名生效时间
ExpiresAt: ExpirationTime.Unix(), // 过期时间
Issuer: “你的KEY”, //签名的发行者
},
}
token, err := AdminJwt.CreateToken(Claims)
if err != nil {
logs.Error(“签名签发错误:%s”, err.Error())
return AdminInfo, errors.New(“签名签发错误!”)
}
通过TOKEN获取成员数据
// 通过token获取账户信息
func CtxTokenGetAdminInfo(claims *jwt.CustomClaims) (Admin, error) {
AdminInfo := Admin{}
c, err := json.Marshal(claims.AdminInfo)
if err != nil {
logs.Error(err)
return AdminInfo, errors.New(“从token中获取账户信息时失败,如果您是系统管理员,您可以通过错误日志查看详细信息”)
}
err = json.Unmarshal(c, &AdminInfo)
if err != nil {
logs.Error(err)
return AdminInfo, errors.New(“从token中获取账户信息时失败,如果您是系统管理员,您可以通过错误日志查看详细信息”)
}
return AdminInfo, err
}
调用
CtxTokenGetAdminInfo(_this.Ctx.Input.GetData(“admin_token_claims”).(*jwt.CustomClaims))
111
声明:
本文采用
BY-NC-SA
协议进行授权,如无注明均为原创,转载请注明转自
一颗大萝北
本文地址: BEEGO实现JWT
本文地址: BEEGO实现JWT