/
token.go
114 lines (94 loc) · 2.62 KB
/
token.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
113
114
package services
import (
"errors"
"io/ioutil"
"strconv"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/jasongauvin/GAUVIN_JASON/api/config"
log "github.com/sirupsen/logrus"
)
type Claims struct {
Email string
jwt.StandardClaims
}
// Rsa is the struct to get the rsa keys used to generate and verify tokens from the environment variables
type Rsa struct {
PublicKeyPath string
PrivateKeyPath string
PublicKey interface{}
PrivateKey interface{}
}
var rsa Rsa
func initRsaKeys() error {
if rsa.PrivateKey != nil && rsa.PublicKey != nil {
return nil
}
rsa.PublicKeyPath = config.GoDotEnvVariable("RSA_PUBLIC_PATH")
rsa.PrivateKeyPath = config.GoDotEnvVariable("RSA_PRIVATE_PATH")
// Get the public key
publicKeyData, err := ioutil.ReadFile(rsa.PublicKeyPath)
if err != nil {
log.Error(err)
return err
}
publicKey, err := jwt.ParseRSAPublicKeyFromPEM(publicKeyData)
if err != nil {
log.Error("error public key: ", err)
return err
}
rsa.PublicKey = publicKey
// Get the private key
privateKeyData, err := ioutil.ReadFile(rsa.PrivateKeyPath)
if err != nil {
log.Error(err)
return err
}
privateKey, err := jwt.ParseRSAPrivateKeyFromPEMWithPassword(privateKeyData, config.GoDotEnvVariable("RSA_PASSWORD"))
if err != nil {
log.Error("error public key: ", err)
return err
}
rsa.PrivateKey = privateKey
return nil
}
// GenerateToken creates a JWT with email and expiration time in the payload
func GenerateToken(email string) (string, error) {
err := initRsaKeys()
if err != nil {
return "", errors.New("Couldn't init rsa keys")
}
validTime, _ := strconv.ParseInt(config.GoDotEnvVariable("TOKEN_VALID_DURATION"), 10, 64)
// Generate Expiration date
expirationTime := time.Now().Add(time.Duration(validTime) * time.Minute)
claims := &Claims{
Email: email,
StandardClaims: jwt.StandardClaims{
// JWT takes unix timestamps
ExpiresAt: expirationTime.Unix(),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
tokenString, err := token.SignedString(rsa.PrivateKey)
if err != nil {
log.Error("error while generating token: ", err)
return "", err
}
return tokenString, nil
}
// DecodeToken decode and validates a token
func DecodeToken(tokenString string) (*jwt.Token, *Claims, error) {
err := initRsaKeys()
if err != nil {
return nil, &Claims{}, errors.New("Couldn't init rsa keys")
}
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
return rsa.PublicKey, nil
})
if err != nil {
log.Error("Couldn't parse the token : ", err)
return nil, &Claims{}, err
}
return token, claims, nil
}