golang-dy-back/internal/handlers/login.go
2025-10-28 16:59:41 +08:00

64 lines
2.0 KiB
Go

package handlers
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/dchest/captcha"
"go-dy/internal/auth"
"go-dy/internal/config"
dbpkg "go-dy/internal/db"
"go-dy/internal/repo"
"go-dy/internal/resp"
)
func LoginHandler(cfg config.Config) gin.HandlerFunc {
return func(c *gin.Context) {
// Expect form data: name, password (+ optional captcha when enabled)
name := c.PostForm("name")
password := c.PostForm("password")
if name == "" || password == "" {
resp.Error(c, http.StatusBadRequest, "missing name or password")
return
}
// captcha gate (if enabled)
if cfg.LoginRequireCaptcha {
cid := c.PostForm("captcha_id")
ccode := c.PostForm("captcha_code")
if cid == "" || ccode == "" {
resp.Error(c, http.StatusBadRequest, "missing captcha_id or captcha_code")
return
}
if !captcha.VerifyString(cid, ccode) {
resp.Error(c, http.StatusUnauthorized, "invalid captcha")
return
}
}
// Database-backed login only: always check users table
db, err := dbpkg.Get(cfg)
if err != nil {
resp.Error(c, http.StatusServiceUnavailable, "database unavailable")
return
}
u, err := repo.GetUserByName(db, name)
if err != nil {
resp.Error(c, http.StatusInternalServerError, "query user failed")
return
}
if u == nil || !repo.CheckPassword(u, password) {
resp.Error(c, http.StatusUnauthorized, "invalid credentials")
return
}
token, err := auth.GenerateToken(name, cfg.JWTSecret, 24*time.Hour)
if err != nil {
resp.Error(c, http.StatusInternalServerError, "could not generate token")
return
}
resp.OK(c, gin.H{"token": token})
}
}