You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
2.9 KiB
Go
131 lines
2.9 KiB
Go
package jwt
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/errors"
|
|
|
|
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/config"
|
|
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/constants"
|
|
"github.com/dgrijalva/jwt-go"
|
|
)
|
|
|
|
type CustomClaims struct {
|
|
User string `json:"user,omitempty"`
|
|
IsRefresh bool `json:"isRefresh,omitempty"`
|
|
jwt.StandardClaims
|
|
}
|
|
|
|
type Token struct {
|
|
Type string
|
|
Access string
|
|
ExpiredPeriode int64
|
|
Refresh string
|
|
}
|
|
|
|
func GenerateToken(config *config.Config, user string) (*Token, error) {
|
|
atoken, err := set(user, false, constants.Jwt_Token_Expired_Periode, config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
arefresh, err := set(user, true, constants.Jwt_Refresh_Expired_Periode, config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Token{
|
|
Type: config.Jwt.Type,
|
|
Access: atoken,
|
|
ExpiredPeriode: constants.Jwt_Token_Expired_Periode,
|
|
Refresh: arefresh,
|
|
}, nil
|
|
}
|
|
|
|
func set(user string, isrefresh bool, exp time.Duration, config *config.Config) (string, error) {
|
|
// create refresh token
|
|
claims := CustomClaims{
|
|
User: user,
|
|
IsRefresh: isrefresh,
|
|
StandardClaims: jwt.StandardClaims{
|
|
ExpiresAt: time.Now().Add(exp * time.Second).Unix(),
|
|
Issuer: config.Jwt.Issuer,
|
|
},
|
|
}
|
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
atoken, err := token.SignedString([]byte(config.Jwt.Key))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return atoken, nil
|
|
}
|
|
|
|
func ClaimToken(config *config.Config, auth string, isrefresh bool) (jwt.MapClaims, error) {
|
|
var token *jwt.Token
|
|
var err error
|
|
|
|
if !isrefresh {
|
|
// Bearer token as RFC 6750 standard
|
|
if strings.Split(auth, " ")[0] != config.Jwt.Type {
|
|
return nil, errors.New("Invalid token")
|
|
}
|
|
|
|
token, err = claim(auth, config.Jwt.Key, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else {
|
|
token, err = claim(auth, config.Jwt.Key, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
claims, ok := token.Claims.(jwt.MapClaims)
|
|
if !ok || !token.Valid {
|
|
return nil, errors.New("failed to claim token")
|
|
}
|
|
|
|
// validate issuer
|
|
if claims["iss"] != config.Jwt.Issuer {
|
|
return nil, errors.New("Invalid token")
|
|
}
|
|
|
|
// validate refresh token
|
|
if isrefresh {
|
|
if claims["IsRefresh"] == false {
|
|
return nil, errors.New("Invalid token")
|
|
}
|
|
} else {
|
|
if claims["IsRefresh"] == true {
|
|
return nil, errors.New("Invalid token")
|
|
}
|
|
}
|
|
|
|
return claims, nil
|
|
}
|
|
|
|
func claim(auth, key string, isrefresh bool) (*jwt.Token, error) {
|
|
if !isrefresh {
|
|
auth = strings.Split(auth, " ")[1]
|
|
}
|
|
|
|
token, err := jwt.Parse(auth, func(token *jwt.Token) (interface{}, error) {
|
|
if method, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
errors.New("Signing method invalid")
|
|
} else if method != jwt.SigningMethodHS256 {
|
|
errors.New("Signing method invalid")
|
|
}
|
|
|
|
return []byte(key), nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return token, nil
|
|
}
|