Files
GPT_Management/internal/handler/auth_handler.go
sar 42c423bd32 feat: 初始化 ChatGPT Team 管理后端项目
- 添加用户认证模块 (JWT + 密码管理)
- 添加 ChatGPT 账户管理功能
- 添加卡密管理功能 (创建、批量生成、查询)
- 添加邀请功能
- 配置数据库迁移和路由系统
2026-01-13 14:42:56 +08:00

139 lines
3.1 KiB
Go

package handler
import (
"encoding/json"
"net/http"
"gpt-manager-go/internal/auth"
"gpt-manager-go/internal/repository"
)
// AuthHandler 认证处理器
type AuthHandler struct {
adminRepo *repository.AdminRepository
}
// NewAuthHandler 创建认证处理器
func NewAuthHandler(adminRepo *repository.AdminRepository) *AuthHandler {
return &AuthHandler{adminRepo: adminRepo}
}
// LoginRequest 登录请求
type LoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
// LoginResponse 登录响应
type LoginResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Token string `json:"token,omitempty"`
User *UserInfo `json:"user,omitempty"`
}
// UserInfo 用户信息
type UserInfo struct {
ID int `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
IsSuperAdmin bool `json:"is_super_admin"`
}
// Login 登录接口
func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
respondJSON(w, http.StatusMethodNotAllowed, LoginResponse{
Success: false,
Message: "Method not allowed",
})
return
}
var req LoginRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
respondJSON(w, http.StatusBadRequest, LoginResponse{
Success: false,
Message: "Invalid request body",
})
return
}
// 验证必填字段
if req.Username == "" || req.Password == "" {
respondJSON(w, http.StatusBadRequest, LoginResponse{
Success: false,
Message: "Username and password are required",
})
return
}
// 查找用户
admin, err := h.adminRepo.FindByUsername(req.Username)
if err != nil {
respondJSON(w, http.StatusInternalServerError, LoginResponse{
Success: false,
Message: "Internal server error",
})
return
}
if admin == nil {
respondJSON(w, http.StatusUnauthorized, LoginResponse{
Success: false,
Message: "Invalid username or password",
})
return
}
// 检查账号是否激活
if !admin.IsActive {
respondJSON(w, http.StatusForbidden, LoginResponse{
Success: false,
Message: "Account is disabled",
})
return
}
// 验证密码
if !auth.CheckPassword(req.Password, admin.PasswordHash) {
respondJSON(w, http.StatusUnauthorized, LoginResponse{
Success: false,
Message: "Invalid username or password",
})
return
}
// 生成 Token
token, err := auth.GenerateToken(admin.ID, admin.Username, admin.IsSuperAdmin)
if err != nil {
respondJSON(w, http.StatusInternalServerError, LoginResponse{
Success: false,
Message: "Failed to generate token",
})
return
}
// 更新最后登录时间
_ = h.adminRepo.UpdateLastLogin(admin.ID)
respondJSON(w, http.StatusOK, LoginResponse{
Success: true,
Message: "Login successful",
Token: token,
User: &UserInfo{
ID: admin.ID,
Username: admin.Username,
Email: admin.Email,
IsSuperAdmin: admin.IsSuperAdmin,
},
})
}
// respondJSON 返回 JSON 响应
func respondJSON(w http.ResponseWriter, status int, data interface{}) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(data)
}