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.
go-grpc_basic/pkg/v1/jwt/jwt.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
}