first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:48:15 +03:00
commit e6f3268c28
50 changed files with 4930 additions and 0 deletions

111
accounts/jwt.go Normal file
View File

@@ -0,0 +1,111 @@
package accounts
import (
"fmt"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
)
type jwtClaims struct {
UserID uint `json:"user_id"`
Role string `json:"role"`
jwt.RegisteredClaims
}
const (
RoleAdmin = "admin"
RoleUser = "user"
)
func GenerateTokens(userID uint, role string) (string, string, error) {
accessSecret := os.Getenv("JWT_SECRET")
refreshSecret := os.Getenv("JWT_REFRESH_SECRET")
if accessSecret == "" || refreshSecret == "" {
return "", "", fmt.Errorf("JWT secrets are not set")
}
normalizedRole := normalizeRole(role)
// Access Token
accessClaims := jwtClaims{
UserID: userID,
Role: normalizedRole,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * time.Minute)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
accessToken := jwt.NewWithClaims(jwt.SigningMethodHS256, accessClaims)
accessString, err := accessToken.SignedString([]byte(accessSecret))
if err != nil {
return "", "", err
}
// Refresh Token
refreshClaims := jwtClaims{
UserID: userID,
Role: normalizedRole,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(7 * 24 * time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims)
refreshString, err := refreshToken.SignedString([]byte(refreshSecret))
if err != nil {
return "", "", err
}
return accessString, refreshString, nil
}
func ParseAccessToken(tokenString string) (uint, error) {
secret := os.Getenv("JWT_SECRET")
claims, err := parseTokenClaims(tokenString, secret)
if err != nil {
return 0, err
}
return claims.UserID, nil
}
func ParseRefreshToken(tokenString string) (uint, error) {
secret := os.Getenv("JWT_REFRESH_SECRET")
claims, err := parseTokenClaims(tokenString, secret)
if err != nil {
return 0, err
}
return claims.UserID, nil
}
func parseAccessClaims(tokenString string) (*jwtClaims, error) {
secret := os.Getenv("JWT_SECRET")
return parseTokenClaims(tokenString, secret)
}
func parseTokenClaims(tokenString, secret string) (*jwtClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &jwtClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(secret), nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*jwtClaims); ok && token.Valid {
claims.Role = normalizeRole(claims.Role)
return claims, nil
}
return nil, fmt.Errorf("invalid token")
}
func normalizeRole(role string) string {
switch role {
case RoleAdmin:
return RoleAdmin
default:
return RoleUser
}
}