-
Notifications
You must be signed in to change notification settings - Fork 19
/
middleware.go
69 lines (58 loc) · 1.76 KB
/
middleware.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
package clerk
import (
"context"
"net/http"
"strings"
)
const (
ActiveSession = iota
ActiveSessionClaims
// TODO: we should use a type alias instead of int, so as to avoid collisions
// with other packages
)
func WithSession(client Client) func(handler http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if token, isAuthV2 := isAuthV2Request(r, client); isAuthV2 {
// Validate using session token
claims, err := client.VerifyToken(token)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
_, _ = w.Write([]byte(err.Error()))
return
}
ctx := context.WithValue(r.Context(), ActiveSessionClaims, claims)
next.ServeHTTP(w, r.WithContext(ctx))
} else {
// Validate using session verify request
session, err := client.Verification().Verify(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write([]byte(err.Error()))
return
}
ctx := context.WithValue(r.Context(), ActiveSession, session)
next.ServeHTTP(w, r.WithContext(ctx))
}
})
}
}
func isAuthV2Request(r *http.Request, client Client) (string, bool) {
// Try with token from header
headerToken := strings.TrimSpace(r.Header.Get("Authorization"))
headerToken = strings.TrimPrefix(headerToken, "Bearer ")
claims, err := client.DecodeToken(headerToken)
if err == nil {
return headerToken, isValidIssuer(claims.Issuer)
}
// Verification from header token failed, try with token from cookie
cookieSession, err := r.Cookie(CookieSession)
if err != nil {
return "", false
}
claims, err = client.DecodeToken(cookieSession.Value)
if err != nil {
return "", false
}
return cookieSession.Value, isValidIssuer(claims.Issuer)
}