query-database/api/internal/handlers/auth.go
2026-03-25 15:46:20 +08:00

93 lines
2.4 KiB
Go

package handlers
import (
"database/sql"
"net/http"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
)
type authReq struct {
Email string `json:"email"`
Password string `json:"password"`
}
func (h *Handlers) Register(c *gin.Context) {
var req authReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": "参数错误"})
return
}
email := strings.TrimSpace(strings.ToLower(req.Email))
if email == "" || len(req.Password) < 6 {
c.JSON(http.StatusBadRequest, gin.H{"message": "邮箱或密码不合法"})
return
}
hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": "服务异常"})
return
}
id := uuid.NewString()
now := time.Now().UTC().Format(time.RFC3339)
_, err = h.sqlite.Exec(
`INSERT INTO users (id, email, password_hash, name, module_key, experience_level, onboarding_completed, created_at)
VALUES (?, ?, ?, '', 'shop', 'beginner', 0, ?)`,
id,
email,
string(hash),
now,
)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": "该邮箱已注册"})
return
}
token, err := h.auth.Issue(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": "服务异常"})
return
}
c.JSON(http.StatusOK, gin.H{"token": token})
}
func (h *Handlers) Login(c *gin.Context) {
var req authReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": "参数错误"})
return
}
email := strings.TrimSpace(strings.ToLower(req.Email))
if email == "" {
c.JSON(http.StatusBadRequest, gin.H{"message": "邮箱或密码不合法"})
return
}
var id string
var hash string
err := h.sqlite.QueryRow(`SELECT id, password_hash FROM users WHERE email = ?`, email).Scan(&id, &hash)
if err != nil {
if err == sql.ErrNoRows {
c.JSON(http.StatusUnauthorized, gin.H{"message": "账号或密码错误"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"message": "服务异常"})
return
}
if bcrypt.CompareHashAndPassword([]byte(hash), []byte(req.Password)) != nil {
c.JSON(http.StatusUnauthorized, gin.H{"message": "账号或密码错误"})
return
}
token, err := h.auth.Issue(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": "服务异常"})
return
}
c.JSON(http.StatusOK, gin.H{"token": token})
}