Skip to content

Commit fc830fe

Browse files
committed
feat: add create jwt logic
1 parent cdc9dde commit fc830fe

File tree

1 file changed

+128
-0
lines changed
  • gmicro/server/restserver/middlewares

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package middlewares
2+
3+
import (
4+
"errors"
5+
"net/http"
6+
"time"
7+
8+
"github.com/dgrijalva/jwt-go"
9+
"github.com/gin-gonic/gin"
10+
)
11+
12+
type CustomClaims struct {
13+
ID uint `json:"userid"`
14+
NickName string
15+
AuthorityId uint
16+
jwt.StandardClaims
17+
}
18+
19+
// TODO 弃用,使用了通用中间件,实现验证
20+
func JWTAuth(signKey string) gin.HandlerFunc {
21+
return func(c *gin.Context) {
22+
// 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localSstorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
23+
token := c.Request.Header.Get("Authorization")
24+
if token == "" {
25+
c.JSON(http.StatusUnauthorized, map[string]string{
26+
"msg": "请登录",
27+
})
28+
c.Abort()
29+
return
30+
}
31+
j := NewJWT(signKey)
32+
// parseToken 解析token包含的信息
33+
claims, err := j.ParseToken(token)
34+
if err != nil {
35+
if err == TokenExpired {
36+
if err == TokenExpired {
37+
c.JSON(http.StatusUnauthorized, map[string]string{
38+
"msg": "授权已过期",
39+
})
40+
c.Abort()
41+
return
42+
}
43+
}
44+
45+
c.JSON(http.StatusUnauthorized, "未登陆")
46+
c.Abort()
47+
return
48+
}
49+
c.Set("claims", claims)
50+
c.Set("userId", claims.ID)
51+
c.Next()
52+
}
53+
}
54+
55+
type JWT struct {
56+
SigningKey []byte
57+
}
58+
59+
var (
60+
TokenExpired = errors.New("token is expired")
61+
TokenNotValidYet = errors.New("token not active yet")
62+
TokenMalformed = errors.New("that's not even a token")
63+
TokenInvalid = errors.New("couldn't handle this token")
64+
)
65+
66+
func NewJWT(sign string) *JWT {
67+
//zap.S().Info(global.ServerConfig.JWTInfo.SigningKey)
68+
return &JWT{
69+
[]byte(sign), //可以设置过期时间
70+
}
71+
}
72+
73+
// 创建一个token
74+
func (j *JWT) CreateToken(claims CustomClaims) (string, error) {
75+
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
76+
return token.SignedString(j.SigningKey)
77+
}
78+
79+
// 解析 token
80+
func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) {
81+
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
82+
return j.SigningKey, nil
83+
})
84+
if err != nil {
85+
if ve, ok := err.(*jwt.ValidationError); ok {
86+
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
87+
return nil, TokenMalformed
88+
} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
89+
// Token is expired
90+
return nil, TokenExpired
91+
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
92+
return nil, TokenNotValidYet
93+
} else {
94+
return nil, TokenInvalid
95+
}
96+
}
97+
}
98+
if token != nil {
99+
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
100+
return claims, nil
101+
}
102+
return nil, TokenInvalid
103+
104+
} else {
105+
return nil, TokenInvalid
106+
107+
}
108+
109+
}
110+
111+
// 更新token
112+
func (j *JWT) RefreshToken(tokenString string) (string, error) {
113+
jwt.TimeFunc = func() time.Time {
114+
return time.Unix(0, 0)
115+
}
116+
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
117+
return j.SigningKey, nil
118+
})
119+
if err != nil {
120+
return "", err
121+
}
122+
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
123+
jwt.TimeFunc = time.Now
124+
claims.StandardClaims.ExpiresAt = time.Now().Add(1 * time.Hour).Unix()
125+
return j.CreateToken(*claims)
126+
}
127+
return "", TokenInvalid
128+
}

0 commit comments

Comments
 (0)