-
Notifications
You must be signed in to change notification settings - Fork 99
/
session_storer.go
100 lines (82 loc) · 3.29 KB
/
session_storer.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
package auth
import (
"errors"
"fmt"
"net/http"
jwt "github.com/golang-jwt/jwt/v4"
"github.com/qor/auth/claims"
"github.com/qor/session"
)
// SessionStorerInterface session storer interface for Auth
type SessionStorerInterface interface {
// Get get claims from request
Get(req *http.Request) (*claims.Claims, error)
// Update update claims with session manager
Update(w http.ResponseWriter, req *http.Request, claims *claims.Claims) error
// Delete delete session
Delete(w http.ResponseWriter, req *http.Request) error
// Flash add flash message to session data
Flash(w http.ResponseWriter, req *http.Request, message session.Message) error
// Flashes returns a slice of flash messages from session data
Flashes(w http.ResponseWriter, req *http.Request) []session.Message
// SignedToken generate signed token with Claims
SignedToken(claims *claims.Claims) string
// ValidateClaims validate auth token
ValidateClaims(tokenString string) (*claims.Claims, error)
}
// SessionStorer default session storer
type SessionStorer struct {
SessionName string
SigningMethod jwt.SigningMethod
SignedString string
SessionManager session.ManagerInterface
}
// Get get claims from request
func (sessionStorer *SessionStorer) Get(req *http.Request) (*claims.Claims, error) {
tokenString := req.Header.Get("Authorization")
// Get Token from Cookie
if tokenString == "" {
tokenString = sessionStorer.SessionManager.Get(req, sessionStorer.SessionName)
}
return sessionStorer.ValidateClaims(tokenString)
}
// Update update claims with session manager
func (sessionStorer *SessionStorer) Update(w http.ResponseWriter, req *http.Request, claims *claims.Claims) error {
token := sessionStorer.SignedToken(claims)
return sessionStorer.SessionManager.Add(w, req, sessionStorer.SessionName, token)
}
// Delete delete claims from session manager
func (sessionStorer *SessionStorer) Delete(w http.ResponseWriter, req *http.Request) error {
sessionStorer.SessionManager.Pop(w, req, sessionStorer.SessionName)
return nil
}
// Flash add flash message to session data
func (sessionStorer *SessionStorer) Flash(w http.ResponseWriter, req *http.Request, message session.Message) error {
return sessionStorer.SessionManager.Flash(w, req, message)
}
// Flashes returns a slice of flash messages from session data
func (sessionStorer *SessionStorer) Flashes(w http.ResponseWriter, req *http.Request) []session.Message {
return sessionStorer.SessionManager.Flashes(w, req)
}
// SignedToken generate signed token with Claims
func (sessionStorer *SessionStorer) SignedToken(claims *claims.Claims) string {
token := jwt.NewWithClaims(sessionStorer.SigningMethod, claims)
signedToken, _ := token.SignedString([]byte(sessionStorer.SignedString))
return signedToken
}
// ValidateClaims validate auth token
func (sessionStorer *SessionStorer) ValidateClaims(tokenString string) (*claims.Claims, error) {
token, err := jwt.ParseWithClaims(tokenString, &claims.Claims{}, func(token *jwt.Token) (interface{}, error) {
if token.Method != sessionStorer.SigningMethod {
return nil, fmt.Errorf("unexpected signing method")
}
return []byte(sessionStorer.SignedString), nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*claims.Claims); ok && token.Valid {
return claims, nil
}
return nil, errors.New("invalid token")
}