Added JWT Refresh token
This commit is contained in:
@@ -12,5 +12,8 @@ API_CACHE_PASSWORD=12345678
|
|||||||
API_MONGODB_URL=mongodb://mongodb:12345678@mongo-db:27017
|
API_MONGODB_URL=mongodb://mongodb:12345678@mongo-db:27017
|
||||||
# EVENTBUS_URL=amqp://guest:guest@api-eventbus:5672
|
# EVENTBUS_URL=amqp://guest:guest@api-eventbus:5672
|
||||||
|
|
||||||
JWT_SECRET_KEY=SomeFancySecretAndRandomString
|
JWT_ACCESS_TOKEN_SECRET_KEY=SomeFancySecretAndRandomString
|
||||||
JWT_TOKEN_EXPIRE_TIME=1 # hours
|
JWT_ACCESS_TOKEN_EXPIRE_TIME=1 # hours
|
||||||
|
|
||||||
|
JWT_REFRESH_TOKEN_SECRET_KEY=SomeFancySecretAndRandomStringAgain
|
||||||
|
JWT_REFRESH_TOKEN_EXPIRE_TIME=7 # days
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
baseCnf "git.ego.freeddns.org/egommerce/go-api-pkg/config"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
jwt "github.com/gofiber/jwt/v2"
|
jwt "github.com/gofiber/jwt/v2"
|
||||||
)
|
)
|
||||||
@@ -12,7 +11,7 @@ import (
|
|||||||
func JWTProtected() func(*fiber.Ctx) error {
|
func JWTProtected() func(*fiber.Ctx) error {
|
||||||
// Create config for JWT authentication middleware.
|
// Create config for JWT authentication middleware.
|
||||||
config := jwt.Config{
|
config := jwt.Config{
|
||||||
SigningKey: []byte(os.Getenv("JWT_SECRET_KEY")),
|
SigningKey: []byte(baseCnf.GetEnv("JWT_ACCESS_TOKEN_SECRET_KEY", "FallbackAccessTokenSecret")),
|
||||||
ContextKey: "jwt", // used in private routes
|
ContextKey: "jwt", // used in private routes
|
||||||
ErrorHandler: jwtError,
|
ErrorHandler: jwtError,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,12 +46,13 @@ func (a *Auth) Login(login, passwd string) (string, error) {
|
|||||||
return "", ErrLoginIncorrect
|
return "", ErrLoginIncorrect
|
||||||
}
|
}
|
||||||
|
|
||||||
token, _ := jwtSrv.CreateToken(id)
|
accessToken, _ := jwtSrv.CreateAccessToken(id)
|
||||||
if err = a.saveTokenToCache(token, id); err != nil {
|
refreshToken, _ := jwtSrv.CreateRefreshToken(id)
|
||||||
|
if err = a.saveTokensToCache(accessToken, refreshToken, id); err != nil {
|
||||||
return "", ErrUnableToCacheToken
|
return "", ErrUnableToCacheToken
|
||||||
}
|
}
|
||||||
|
|
||||||
return token, nil
|
return accessToken, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Auth) Register(email, login, passwd string) (string, error) {
|
func (a *Auth) Register(email, login, passwd string) (string, error) {
|
||||||
@@ -70,10 +71,15 @@ func (a *Auth) Register(email, login, passwd string) (string, error) {
|
|||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Auth) saveTokenToCache(token, id string) error {
|
func (a *Auth) saveTokensToCache(accessToken, refreshToken, id string) error {
|
||||||
res := a.cache.Set(context.Background(), "auth:token:"+id, token, tokenExpireTime)
|
res := a.cache.Set(context.Background(), "auth:access_token:"+id, accessToken, accessTokenExpireTime)
|
||||||
if err := res.Err(); err != nil {
|
if err := res.Err(); err != nil {
|
||||||
fmt.Println("failed to save token in redis: ", err.Error())
|
fmt.Println("failed to save access token in redis: ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
res = a.cache.Set(context.Background(), "auth:refresh_token:"+id, refreshToken, refreshTokenExpireTime)
|
||||||
|
if err := res.Err(); err != nil {
|
||||||
|
fmt.Println("failed to save refresh token in redis: ", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -10,33 +10,55 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tokenExpireTime time.Duration
|
accessTokenExpireTime time.Duration
|
||||||
|
refreshTokenExpireTime time.Duration
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
min, _ := strconv.Atoi(baseCnf.GetEnv("JWT_TOKEN_EXPIRE_TIME", "5"))
|
expAccessTokenTime, _ := strconv.Atoi(baseCnf.GetEnv("JWT_ACCESS_TOKEN_EXPIRE_TIME", "5"))
|
||||||
tokenExpireTime = time.Duration(int(time.Hour) * min)
|
accessTokenExpireTime = time.Duration(int(time.Hour) * expAccessTokenTime) // hours
|
||||||
|
|
||||||
|
expRefreshTokenTime, _ := strconv.Atoi(baseCnf.GetEnv("JWT_REFRESH_TOKEN_EXPIRE_TIME", "7"))
|
||||||
|
refreshTokenExpireTime = time.Duration(int(time.Hour*24) * expRefreshTokenTime) // days
|
||||||
|
|
||||||
jwtSrv = &JWT{
|
jwtSrv = &JWT{
|
||||||
tokenExpireTime,
|
accessTokenExpireTime,
|
||||||
[]byte(baseCnf.GetEnv("JWT_SECRET_KEY", "B413IlIv9nKQfsMCXTE0Cteo4yHgUEfqaLfjg73sNlh")),
|
[]byte(baseCnf.GetEnv("JWT_ACCESS_TOKEN_SECRET_KEY", "FallbackAccessTokenSecret")),
|
||||||
|
refreshTokenExpireTime,
|
||||||
|
[]byte(baseCnf.GetEnv("JWT_REFRESH_TOKEN_SECRET_KEY", "FallbackRefreshTokenSecret")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type JWT struct {
|
type JWT struct {
|
||||||
tokenExpireTime time.Duration
|
accessTokenExpireTime time.Duration
|
||||||
tokenSecret []byte
|
accessTokenSecret []byte
|
||||||
|
|
||||||
|
refreshTokenExpireTime time.Duration
|
||||||
|
refreshTokenSecret []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *JWT) CreateToken(id string) (string, error) {
|
func (s *JWT) CreateAccessToken(id string) (string, error) {
|
||||||
claims := &jwt.StandardClaims{
|
claims := &jwt.StandardClaims{
|
||||||
Id: id,
|
Subject: id,
|
||||||
ExpiresAt: time.Now().Add(time.Duration(s.tokenExpireTime) * time.Minute).Unix(),
|
IssuedAt: time.Now().Unix(),
|
||||||
|
ExpiresAt: time.Now().Add(s.accessTokenExpireTime).Unix(),
|
||||||
}
|
}
|
||||||
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
|
||||||
return token.SignedString(s.tokenSecret)
|
return token.SignedString(s.accessTokenSecret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *JWT) CreateRefreshToken(id string) (string, error) {
|
||||||
|
claims := &jwt.StandardClaims{
|
||||||
|
Subject: id,
|
||||||
|
IssuedAt: time.Now().Unix(),
|
||||||
|
ExpiresAt: time.Now().Add(s.refreshTokenExpireTime).Unix(),
|
||||||
|
}
|
||||||
|
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
|
||||||
|
return token.SignedString(s.accessTokenSecret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *JWT) ValidateToken(tokenStr string) error {
|
func (s *JWT) ValidateToken(tokenStr string) error {
|
||||||
@@ -46,7 +68,7 @@ func (s *JWT) ValidateToken(tokenStr string) error {
|
|||||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.tokenSecret, nil
|
return s.accessTokenSecret, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if _, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
if _, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||||
|
|||||||
Reference in New Issue
Block a user