121 lines
3.5 KiB
Go
121 lines
3.5 KiB
Go
package utils
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
models "kemendagri/sipd/services/sipd_auth/model"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v4"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
type MyCustomClaim struct {
|
|
jwt.RegisteredClaims
|
|
Tahun int `json:"tahun"`
|
|
IdUser int64 `json:"id_user"`
|
|
IdDaerah int64 `json:"id_daerah"`
|
|
KodeProvinsi string `json:"kode_provinsi"`
|
|
KodeDdn string `json:"kode_ddn"`
|
|
IdSkpd int64 `json:"id_skpd"`
|
|
IdRole int `json:"id_role"`
|
|
IdPegawai int64 `json:"id_pegawai"`
|
|
SubDomainDaerah string `json:"sub_domain_daerah" xml:"sub_domain_daerah"`
|
|
}
|
|
|
|
type JWTManager struct {
|
|
secretKey string
|
|
issuer string
|
|
}
|
|
|
|
func NewJWTManager(secretKey, iss string) *JWTManager {
|
|
return &JWTManager{secretKey, iss}
|
|
}
|
|
|
|
func (m *JWTManager) Generate(dbConn *pgxpool.Pool, user models.User, tahun int, idPeg int64) (token, refreshToken string, jwtExpDuration time.Duration, err error) {
|
|
// ambil data durasi expired jwt dan refresh_token dari table sys config
|
|
var jwtExpiredMinutes, refreshTokenExpiredHour int64
|
|
|
|
jwtExpiredMinutes, err = strconv.ParseInt(os.Getenv("JWT_EXPIRED_MINUTES"), 10, 64)
|
|
refreshTokenExpiredHour, err = strconv.ParseInt(os.Getenv("REFRESH_TOKEN_EXPIRED_HOUR"), 10, 64)
|
|
|
|
jwtSub := fmt.Sprintf("%d.%d", user.IdUser, user.IdDaerah)
|
|
|
|
jwtExpDuration = time.Duration(jwtExpiredMinutes) * time.Minute
|
|
|
|
// Create jwt token
|
|
jwtClaims := MyCustomClaim{
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
Issuer: m.issuer,
|
|
Subject: jwtSub,
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtExpDuration)),
|
|
IssuedAt: &jwt.NumericDate{Time: time.Now()},
|
|
},
|
|
Tahun: tahun,
|
|
IdUser: user.IdUser,
|
|
IdDaerah: user.IdDaerah,
|
|
KodeProvinsi: user.KodeProvinsi,
|
|
KodeDdn: user.KodeDdn,
|
|
IdSkpd: user.IdSkpd,
|
|
IdRole: user.IdRole,
|
|
IdPegawai: idPeg,
|
|
SubDomainDaerah: user.SubDomainDaerah,
|
|
}
|
|
token, err = jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims).SignedString([]byte(m.secretKey))
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// Create refresh token
|
|
refreshTokenClaims := MyCustomClaim{
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
Issuer: m.issuer,
|
|
Subject: jwtSub,
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * time.Duration(refreshTokenExpiredHour))),
|
|
IssuedAt: &jwt.NumericDate{Time: time.Now()},
|
|
},
|
|
Tahun: tahun,
|
|
IdUser: user.IdUser,
|
|
IdDaerah: user.IdDaerah,
|
|
KodeProvinsi: user.KodeProvinsi,
|
|
KodeDdn: user.KodeDdn,
|
|
IdSkpd: user.IdSkpd,
|
|
IdRole: user.IdRole,
|
|
IdPegawai: idPeg,
|
|
SubDomainDaerah: user.SubDomainDaerah,
|
|
}
|
|
/*refreshTokenClaims := jwt.RegisteredClaims{
|
|
Issuer: m.issuer,
|
|
Subject: jwtSub,
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * time.Duration(refreshTokenExpiredHour))),
|
|
IssuedAt: &jwt.NumericDate{Time: time.Now()},
|
|
}*/
|
|
refreshToken, err = jwt.NewWithClaims(jwt.SigningMethodHS256, refreshTokenClaims).SignedString([]byte(m.secretKey))
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (m *JWTManager) Verify(token string) (*MyCustomClaim, error) {
|
|
var r *MyCustomClaim
|
|
tDecoded, err := jwt.ParseWithClaims(token, &MyCustomClaim{}, func(token *jwt.Token) (interface{}, error) {
|
|
return []byte(m.secretKey), nil
|
|
})
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
|
|
if claims, ok := tDecoded.Claims.(*MyCustomClaim); ok && tDecoded.Valid {
|
|
if claims.ExpiresAt.Unix() < time.Now().Unix() {
|
|
return r, errors.New("token expired")
|
|
}
|
|
return claims, nil
|
|
}
|
|
|
|
return r, errors.New("invalid token")
|
|
}
|