go-mongo/utils/token.go

89 lines
1.8 KiB
Go

package utils
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/mitchellh/mapstructure"
)
func GetTokenFromHeader(r *http.Request) (string, error) {
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
return "", fmt.Errorf("there is no authorization header provided")
}
authSlice := strings.Split(authHeader, " ")
if len(authSlice) != 2 {
return "", fmt.Errorf("wrong access token or header format")
}
return strings.TrimSpace(authSlice[1]), nil
}
func GetTokenFromCookie(r *http.Request) (string, error) {
cookie, err := r.Cookie("access_token")
if err != nil {
return "", fmt.Errorf("there is no authorization cookie provided")
}
return strings.TrimSpace(cookie.Value), nil
}
func GetUserFromToken[T any](tokenString string, secret string) (*T, error) {
token, err := jwt.Parse(tokenString, func(t *jwt.Token) (any, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("wrong token format ")
}
return []byte(secret), nil
})
if err != nil {
return nil, err
}
if !token.Valid {
return nil, fmt.Errorf("token is not valid")
}
var user *T
claims := token.Claims.(jwt.MapClaims)
if err := mapstructure.Decode(claims["data"], &user); err != nil {
return nil, fmt.Errorf("error while decoding payload claim")
}
return user, nil
}
func CreateToken(sub, secret, expiry string, payload any) (*string, error) {
duration, err := time.ParseDuration(expiry)
if err != nil {
return nil, err
}
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["sub"] = sub
claims["exp"] = time.Now().Add(duration).Unix()
claims["data"] = payload
signedToken, err := token.SignedString([]byte(secret))
if err != nil {
return nil, err
}
return &signedToken, nil
}