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

说点什么
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...