forked from dhax/go-base
-
Notifications
You must be signed in to change notification settings - Fork 0
/
jwt.go
112 lines (95 loc) · 2.47 KB
/
jwt.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package auth
import (
"net/http"
"time"
"github.com/go-chi/jwtauth"
"github.com/spf13/viper"
)
// AppClaims represent the claims extracted from JWT token.
type AppClaims struct {
ID int
Sub string
Roles []string
}
// TokenAuth implements JWT authentication flow.
type TokenAuth struct {
JwtAuth *jwtauth.JwtAuth
jwtExpiry time.Duration
jwtRefreshExpiry time.Duration
}
// NewTokenAuth configures and returns a JWT authentication instance.
func NewTokenAuth() (*TokenAuth, error) {
secret := viper.GetString("auth_jwt_secret")
if secret == "random" {
secret = randStringBytes(32)
}
a := &TokenAuth{
JwtAuth: jwtauth.New("HS256", []byte(secret), nil),
jwtExpiry: viper.GetDuration("auth_jwt_expiry"),
jwtRefreshExpiry: viper.GetDuration("auth_jwt_refresh_expiry"),
}
return a, nil
}
// Verifier http middleware will verify a jwt string from a http request.
func (a *TokenAuth) Verifier() func(http.Handler) http.Handler {
return jwtauth.Verifier(a.JwtAuth)
}
// GenTokenPair returns both an access token and a refresh token.
func (a *TokenAuth) GenTokenPair(ca jwtauth.Claims, cr jwtauth.Claims) (string, string, error) {
access, err := a.CreateJWT(ca)
if err != nil {
return "", "", err
}
refresh, err := a.CreateRefreshJWT(cr)
if err != nil {
return "", "", err
}
return access, refresh, nil
}
// CreateJWT returns an access token for provided account claims.
func (a *TokenAuth) CreateJWT(c jwtauth.Claims) (string, error) {
c.SetIssuedNow()
c.SetExpiryIn(a.jwtExpiry)
_, tokenString, err := a.JwtAuth.Encode(c)
return tokenString, err
}
// CreateRefreshJWT returns a refresh token for provided token Claims.
func (a *TokenAuth) CreateRefreshJWT(c jwtauth.Claims) (string, error) {
c.SetIssuedNow()
c.SetExpiryIn(a.jwtRefreshExpiry)
_, tokenString, err := a.JwtAuth.Encode(c)
return tokenString, err
}
func parseClaims(c jwtauth.Claims) (AppClaims, bool) {
var claims AppClaims
allOK := true
id, ok := c.Get("id")
if !ok {
allOK = false
}
claims.ID = int(id.(float64))
sub, ok := c.Get("sub")
if !ok {
allOK = false
}
claims.Sub = sub.(string)
rl, ok := c.Get("roles")
if !ok {
allOK = false
}
var roles []string
if rl != nil {
for _, v := range rl.([]interface{}) {
roles = append(roles, v.(string))
}
}
claims.Roles = roles
return claims, allOK
}
func parseRefreshClaims(c jwtauth.Claims) (string, bool) {
token, ok := c.Get("token")
if !ok {
return "", false
}
return token.(string), ok
}