| package main |
|
|
| import ( |
| "net/http" |
| "time" |
| "github.com/gin-gonic/gin" |
| "github.com/golang-jwt/jwt/v5" |
| "golang.org/x/crypto/bcrypt" |
| ) |
|
|
| type Claims struct { |
| UserID string `json:"uid"` |
| jwt.RegisteredClaims |
| } |
|
|
| func HashPassword(pwd string) (string, error) { |
| bytes, err := bcrypt.GenerateFromPassword([]byte(pwd), 12) |
| return string(bytes), err |
| } |
|
|
| func CheckPassword(hash, pwd string) bool { |
| return bcrypt.CompareHashAndPassword([]byte(hash), []byte(pwd)) == nil |
| } |
|
|
| func GenerateToken(userID string) (string, error) { |
| claims := Claims{ |
| UserID: userID, |
| RegisteredClaims: jwt.RegisteredClaims{ |
| ExpiresAt: jwt.NewNumericDate(time.Now().Add(7 * 24 * time.Hour)), |
| IssuedAt: jwt.NewNumericDate(time.Now()), |
| }, |
| } |
| token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) |
| return token.SignedString(jwtSecret) |
| } |
|
|
| func SetTokenCookie(c *gin.Context, token string) { |
| c.SetSameSite(http.SameSiteLaxMode) |
| c.SetCookie("token", token, 3600*24*7, "/", "", false, true) |
| } |
|
|
| func ClearTokenCookie(c *gin.Context) { |
| c.SetCookie("token", "", -1, "/", "", false, true) |
| } |
|
|
| func AuthMiddleware() gin.HandlerFunc { |
| return func(c *gin.Context) { |
| tokenStr, err := c.Cookie("token") |
| if err != nil { |
| c.AbortWithStatusJSON(401, gin.H{"error": "Unauthorized"}); return |
| } |
| claims := &Claims{} |
| token, err := jwt.ParseWithClaims(tokenStr, claims, func(t *jwt.Token) (interface{}, error) { return jwtSecret, nil }) |
| if err != nil || !token.Valid { |
| c.AbortWithStatusJSON(401, gin.H{"error": "Invalid token"}); return |
| } |
| c.Set("userID", claims.UserID) |
| c.Next() |
| } |
| } |
|
|
| |
| func OptionalAuth() gin.HandlerFunc { |
| return func(c *gin.Context) { |
| tokenStr, _ := c.Cookie("token") |
| if tokenStr != "" { |
| claims := &Claims{} |
| if token, _ := jwt.ParseWithClaims(tokenStr, claims, func(t *jwt.Token) (interface{}, error) { return jwtSecret, nil }); token.Valid { |
| c.Set("userID", claims.UserID) |
| } |
| } |
| c.Next() |
| } |
| } |