2023-10-27 09:51:58 +00:00
|
|
|
package jwttoken
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/golang-jwt/jwt/v4"
|
2023-10-27 22:12:56 +00:00
|
|
|
"online-order/configs"
|
2023-10-27 09:51:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// GenerateToken generates token when user connects himself
|
|
|
|
func GenerateToken(user_id string) (map[string]string, error) {
|
|
|
|
accessclaims := make(jwt.MapClaims) // access token claim
|
2023-10-27 22:12:56 +00:00
|
|
|
refreshclaims := make(jwt.MapClaims) //refresh token claim
|
2023-10-27 09:51:58 +00:00
|
|
|
now_time := time.Now().UTC()
|
2023-10-27 22:12:56 +00:00
|
|
|
conf := configs.LoadConfigEnv() //LoadConfigEnv() //Load .env settings
|
2023-10-27 09:51:58 +00:00
|
|
|
|
|
|
|
// Generate access token
|
|
|
|
accessclaims["authorized"] = true
|
|
|
|
accessclaims["sub"] = user_id
|
|
|
|
accessclaims["exp"] = now_time.Add(time.Hour * time.Duration(conf.AccessTokenHourLifespan)).Unix()
|
|
|
|
//accessclaims["exp"] = now_time.Add(time.Hour * time.Duration(configs.GetInt("ACCESS_TOKEN_HOUR_LIFESPAN"))).Unix()
|
|
|
|
accessclaims["iat"] = now_time.Unix()
|
|
|
|
accessclaims["nbf"] = now_time.Unix()
|
|
|
|
|
|
|
|
accesstoken := jwt.NewWithClaims(jwt.SigningMethodHS256, accessclaims)
|
|
|
|
at, err := accesstoken.SignedString([]byte(conf.AccessTokenSecret))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate refresh token
|
|
|
|
refreshclaims["authorized"] = true
|
|
|
|
refreshclaims["sub"] = user_id
|
|
|
|
refreshclaims["exp"] = now_time.Add(time.Hour * time.Duration(conf.RefreshTokenHourLifespan)).Unix()
|
|
|
|
refreshclaims["iat"] = now_time.Unix()
|
|
|
|
refreshclaims["nbf"] = now_time.Unix()
|
|
|
|
|
|
|
|
refreshtoken := jwt.NewWithClaims(jwt.SigningMethodHS256, accessclaims)
|
|
|
|
rt, err := refreshtoken.SignedString([]byte(conf.RefreshTokenSecret))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return map[string]string{"access_token": at, "refresh_token": rt}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExtractToken retrieves the token send by the user in every request
|
|
|
|
func ExtractToken(ctx *gin.Context) string {
|
|
|
|
conf := configs.LoadConfigEnv()
|
2023-10-27 22:12:56 +00:00
|
|
|
|
2023-10-27 09:51:58 +00:00
|
|
|
bearerToken := ctx.Request.Header.Get("Authorization")
|
|
|
|
// If the token doesn not start with a good prefix: like Bearer, Token, ..., we return empty string
|
|
|
|
if !strings.HasPrefix(bearerToken, conf.TokenPrefix) {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(strings.Split(bearerToken, " ")) == 2 {
|
|
|
|
return strings.Split(bearerToken, " ")[1]
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsTokenValid check if a token is valid and not expired
|
|
|
|
func IsTokenValid(ctx *gin.Context) (string, error) {
|
|
|
|
tokenString := ExtractToken(ctx)
|
|
|
|
conf := configs.LoadConfigEnv()
|
|
|
|
|
2023-10-27 22:12:56 +00:00
|
|
|
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
2023-10-27 09:51:58 +00:00
|
|
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
|
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
|
|
|
}
|
|
|
|
return []byte(conf.AccessTokenSecret), nil
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
if claim, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
|
|
|
return claim["sub"].(string), nil
|
|
|
|
}
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExtractTokenID extracts the user ID on a Token from Access token
|
|
|
|
func ExtractClaimsFromAccess(ctx *gin.Context) (jwt.MapClaims, error) {
|
|
|
|
tokenString := ExtractToken(ctx)
|
|
|
|
conf := configs.LoadConfigEnv()
|
|
|
|
|
2023-10-27 22:12:56 +00:00
|
|
|
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
2023-10-27 09:51:58 +00:00
|
|
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
|
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
|
|
|
}
|
|
|
|
return []byte(conf.AccessTokenSecret), nil
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
claims, ok := token.Claims.(jwt.MapClaims)
|
|
|
|
if ok && token.Valid {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return claims, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExtractTokenID extracts the user ID on a Token from refresh token
|
|
|
|
func ExtractClaimsFromRefresh(refresh_string string) (jwt.MapClaims, error) {
|
|
|
|
conf := configs.LoadConfigEnv()
|
|
|
|
|
2023-10-27 22:12:56 +00:00
|
|
|
token, err := jwt.Parse(refresh_string, func(token *jwt.Token) (interface{}, error) {
|
2023-10-27 09:51:58 +00:00
|
|
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
|
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
|
|
|
}
|
|
|
|
return []byte(conf.RefreshTokenSecret), nil
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
claims, ok := token.Claims.(jwt.MapClaims)
|
|
|
|
if ok && token.Valid {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return claims, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check refresh token
|
|
|
|
func RefreshToken(ctx *gin.Context, refresh_string string) (map[string]string, error) {
|
|
|
|
conf := configs.LoadConfigEnv()
|
|
|
|
|
2023-10-27 22:12:56 +00:00
|
|
|
rtoken, err := jwt.Parse(refresh_string, func(token *jwt.Token) (interface{}, error) {
|
2023-10-27 09:51:58 +00:00
|
|
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
|
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
|
|
|
}
|
|
|
|
return []byte(conf.RefreshTokenSecret), nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if refreshClaim, ok := rtoken.Claims.(jwt.MapClaims); ok && rtoken.Valid {
|
|
|
|
return GenerateToken(refreshClaim["sub"].(string))
|
|
|
|
}
|
|
|
|
return nil, err
|
2023-10-27 22:12:56 +00:00
|
|
|
}
|