-
Notifications
You must be signed in to change notification settings - Fork 10
/
auth.go
78 lines (67 loc) · 1.79 KB
/
auth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package middleware
import (
"net/http"
"strings"
"unicode/utf8"
"github.com/gin-gonic/gin"
"github.com/totoval/framework/config"
"github.com/totoval/framework/utils/jwt"
)
const (
CONTEXT_CLAIM_KEY = "TOTOVAL_CONTEXT_CLAIM"
CONTEXT_TOKEN_KEY = "TOTOVAL_CONTEXT_TOKEN"
)
type TokenRevokeError struct{}
func (e TokenRevokeError) Error() string {
return "token revoke failed"
}
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.DefaultQuery("token", "")
if token == "" {
token = c.Request.Header.Get("Authorization")
if s := strings.Split(token, " "); len(s) == 2 {
token = s[1]
}
}
// set token
c.Set(CONTEXT_TOKEN_KEY, token)
j := jwt.NewJWT(config.GetString("auth.sign_key"))
claims, err := j.ParseToken(token)
if err != nil {
if err == jwt.TokenExpired {
if token, _err := j.RefreshTokenUnverified(token); _err == nil {
if claims, err := j.ParseToken(token); err == nil {
c.Set(CONTEXT_CLAIM_KEY, claims)
c.Header("Authorization", "Bear "+token)
//c.JSON(http.StatusOK, gin.H{"data": gin.H{"token": token}})
return
}
}
}
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
return
}
c.Set(CONTEXT_CLAIM_KEY, claims)
}
}
func AuthClaimID(c *gin.Context) (ID uint, exist bool) {
claims, exist := c.Get(CONTEXT_CLAIM_KEY)
if !exist {
return 0, false
}
r, _ := utf8.DecodeRune([]byte(claims.(*jwt.UserClaims).ID))
return uint(r), true
}
func Revoke(c *gin.Context) error {
j := jwt.NewJWT(config.GetString("auth.sign_key"))
if tokenString, exist := c.Get(CONTEXT_TOKEN_KEY); exist {
if token, ok := tokenString.(string); ok {
if err := j.RevokeToken(token); err == nil {
c.Header("Authorization", "")
return nil
}
}
}
return TokenRevokeError{}
}