created: jwt provider
This commit is contained in:
parent
7e5010ac78
commit
bc2038ef34
3 changed files with 139 additions and 0 deletions
|
|
@ -3,6 +3,7 @@ package config
|
|||
type Config struct {
|
||||
AppConf AppConfig
|
||||
DBConf DatabaseConfig
|
||||
JWTConf JWTConfig
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
|
|
@ -23,6 +24,13 @@ type DatabaseConfig struct {
|
|||
LogLevel string
|
||||
}
|
||||
|
||||
type JWTConfig struct {
|
||||
Secret string
|
||||
Issuer string
|
||||
AccessExpire string
|
||||
RefreshExpire string
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
return &Config{
|
||||
AppConf: AppConfig{
|
||||
|
|
@ -42,5 +50,12 @@ func NewConfig() *Config {
|
|||
DBName: getEnv("DB_NAME", ""),
|
||||
LogLevel: getEnv("DB_LOGLEVEL", ""),
|
||||
},
|
||||
|
||||
JWTConf: JWTConfig{
|
||||
Secret: getEnv("JWT_SECRET", ""),
|
||||
Issuer: getEnv("JWT_ISSUER", ""),
|
||||
AccessExpire: getEnv("JWT_ACCESS_EXPIRE", ""),
|
||||
RefreshExpire: getEnv("JWT_REFRESH_EXPIRE", ""),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7
internal/interfaces/jwtProvider.go
Normal file
7
internal/interfaces/jwtProvider.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package interfaces
|
||||
|
||||
type JWTProvider interface {
|
||||
CreateAccessToken(userUuid string) (string, error)
|
||||
CreateRefreshToken(userUuid, tokenUuid string) (string, int64, error)
|
||||
Parse(token string) (string, string, error)
|
||||
}
|
||||
117
internal/provider/token/service.go
Normal file
117
internal/provider/token/service.go
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
package token
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type JWT struct {
|
||||
SecretKey string
|
||||
Issuer string
|
||||
AccessExpire time.Duration
|
||||
RefreshExpire time.Duration
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
SecretKey string
|
||||
Issuer string
|
||||
AccessExpire string
|
||||
RefreshExpire string
|
||||
}
|
||||
|
||||
func NewJWT(deps Deps) *JWT {
|
||||
return &JWT{
|
||||
SecretKey: deps.SecretKey,
|
||||
Issuer: deps.Issuer,
|
||||
AccessExpire: duration(deps.AccessExpire),
|
||||
RefreshExpire: duration(deps.RefreshExpire),
|
||||
}
|
||||
}
|
||||
|
||||
func (j *JWT) CreateAccessToken(userUuid string) (string, error) {
|
||||
now := time.Now()
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"exp": now.Add(j.AccessExpire).Unix(),
|
||||
"iat": now.Unix(),
|
||||
"iss": j.Issuer,
|
||||
"nbf": now.Unix(),
|
||||
"sub": userUuid,
|
||||
})
|
||||
|
||||
signedToken, err := token.SignedString([]byte(j.SecretKey))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return signedToken, nil
|
||||
}
|
||||
|
||||
func (j *JWT) CreateRefreshToken(userUuid, tokenUuid string) (string, int64, error) {
|
||||
now := time.Now()
|
||||
exp := now.Add(j.RefreshExpire).Unix()
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"exp": exp,
|
||||
"iat": now.Unix(),
|
||||
"iss": j.Issuer,
|
||||
"nbf": now.Unix(),
|
||||
"sub": userUuid,
|
||||
"tkn": tokenUuid,
|
||||
})
|
||||
|
||||
signedToken, err := token.SignedString([]byte(j.SecretKey))
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
|
||||
return signedToken, exp, nil
|
||||
|
||||
}
|
||||
|
||||
func (j *JWT) Parse(token string) (string, string, error) {
|
||||
if strings.HasPrefix(token, "Bearer ") {
|
||||
token = strings.TrimPrefix(token, "Bearer ")
|
||||
}
|
||||
|
||||
parse, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return []byte(j.SecretKey), nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if claims, ok := parse.Claims.(jwt.MapClaims); ok && parse.Valid {
|
||||
userUuid := claims["sub"].(string)
|
||||
|
||||
var refreshUuid string
|
||||
if tkn, exists := claims["tkn"]; exists {
|
||||
if tknStr, okay := tkn.(string); okay {
|
||||
refreshUuid = tknStr
|
||||
} else {
|
||||
return "", "", fmt.Errorf("invalid type for 'tkn' claim")
|
||||
}
|
||||
}
|
||||
|
||||
return userUuid, refreshUuid, nil
|
||||
}
|
||||
|
||||
return "", "", fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
func duration(minutes string) time.Duration {
|
||||
dur, err := strconv.Atoi(minutes)
|
||||
if err != nil {
|
||||
return time.Duration(10) * time.Minute
|
||||
}
|
||||
|
||||
return time.Duration(dur) * time.Minute
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue