QuizZip / auth.go
NathMen12's picture
Create auth.go
eedfe00 verified
Raw
History Blame Contribute Delete
1.97 kB
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) // HttpOnly
}
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()
}
}
// Optional Auth (for public quiz view)
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()
}
}