aboutsummaryrefslogtreecommitdiff
path: root/api/auth_jwt.go
blob: f713f4e9be9ef710da6f14e881a6db5f85a67c24 (plain) (blame)
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
package api

import (
	"fmt"
	"strings"
	"time"

	"immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front/db"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

// Static secret.
var JWT_SECRET []byte

type JwtClaims struct {
	Authorized bool  `json:"authorized"`
	Subject    int64 `json:"sub,omitempty"`
	jwt.StandardClaims
}

func SetJwtSecretKey(secret string) {
	JWT_SECRET = []byte(secret)
}

func VerifyJwtToken(token string) (JwtClaims, error) {
	if len(JWT_SECRET) == 0 {
		return JwtClaims{}, fmt.Errorf("not initialized jwt secret")
	}

	t, err := jwt.ParseWithClaims(token, &JwtClaims{}, func(t *jwt.Token) (interface{}, error) {
		if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", t.Header["alg"])
		}

		return JWT_SECRET, nil
	})

	claims, ok := t.Claims.(*JwtClaims)

	if !ok || !t.Valid || err != nil {
		return JwtClaims{}, fmt.Errorf("invalid token (err: %v, claimsok: %v)", err, ok)
	}

	return *claims, nil
}

func SignJwt(claims JwtClaims) (string, error) {
	if len(JWT_SECRET) == 0 {
		return "", fmt.Errorf("not initialized jwt secret")
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, &claims)

	return token.SignedString(JWT_SECRET)
}

func CreateJwtToken(userId int64) (string, error) {
	claims := JwtClaims{
		false,
		userId,
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
		},
	}

	return SignJwt(claims)
}

func GetBearerToken(header string) (string, error) {
	const prefix = "Bearer "

	if !strings.HasPrefix(header, prefix) {
		return "", fmt.Errorf("invalid authorization token")
	}

	return header[len(prefix):], nil
}

func JwtAuth(c *gin.Context) *Error {
	token, err := GetBearerToken(c.GetHeader("Authorization"))
	if err != nil {
		return &Error{NotAuthorized, "not authorized", err}
	}

	claims, err := VerifyJwtToken(token)
	if err != nil {
		return &Error{NotAuthorized, "not authorized", err}
	}

	user, err := db.GetUserById(claims.Subject)
	if err != nil {
		return &Error{NotAuthorized, "not authorized", err}
	}

	c.Set("user", *user)
	c.Set("claims", claims)

	return nil
}

func GetClaims(c *gin.Context) JwtClaims {
	claims, _ := c.Get("claims")

	return claims.(JwtClaims)
}