-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjwt.go
57 lines (48 loc) · 1.55 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
package common
import (
"encoding/base64"
"errors"
"strings"
"github.com/goccy/go-json"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
)
var (
ErrJWTTokenRequired = errors.New("jwt token required")
ErrInvalidJWTToken = errors.New("invalid jwt token")
)
// ParseJWTToken extracts and parse token, whatever start with "Bearer " or not
func ParseJWTToken(token string, user any) error {
// remove "Bearer " prefix if exists
if strings.HasPrefix(token, "Bearer ") {
token = token[7:]
}
token = strings.TrimSpace(token)
payloads := strings.SplitN(token, ".", 3) // extract "Bearer "
if len(payloads) < 3 {
return ErrJWTTokenRequired
}
payloadString := payloads[1]
// jwt encoding ignores padding, so RawStdEncoding should be used instead of StdEncoding
// jwt encoding uses url safe base64 encoding, so RawURLEncoding should be used instead of RawStdEncoding
payloadBytes, err := base64.RawURLEncoding.DecodeString(payloadString) // the middle one is payload
if err != nil {
log.Err(err).Str("payload_string", payloadString).Msg("jwt parse error")
return ErrInvalidJWTToken
}
err = json.Unmarshal(payloadBytes, user)
if err != nil {
log.Err(err).Str("payload_string", payloadString).Msg("jwt parse error")
return ErrInvalidJWTToken
}
return nil
}
// GetJWTToken extracts token from header or cookie
// return empty string if not found
func GetJWTToken(c *fiber.Ctx) string {
tokenString := c.Get("Authorization") // token in header
if tokenString == "" {
tokenString = c.Cookies("access") // token in cookie
}
return tokenString
}