用户登录和接口鉴权
This commit is contained in:
126
internal/controller/user/user.go
Normal file
126
internal/controller/user/user.go
Normal file
@@ -0,0 +1,126 @@
|
||||
// Package user 提供用户相关功能的控制器
|
||||
// 实现用户注册、登录等操作
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/api/middleware"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/logs"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/storage/repository"
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// Controller 用户控制器
|
||||
type Controller struct {
|
||||
userRepo repository.UserRepo
|
||||
logger *logs.Logger
|
||||
}
|
||||
|
||||
// NewController 创建用户控制器实例
|
||||
func NewController(userRepo repository.UserRepo) *Controller {
|
||||
return &Controller{
|
||||
userRepo: userRepo,
|
||||
logger: logs.NewLogger(),
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterRequest 注册请求结构体
|
||||
type RegisterRequest struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
|
||||
// RegisterResponse 注册响应结构体
|
||||
type RegisterResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Username string `json:"username"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// Register 用户注册
|
||||
func (c *Controller) Register(ctx *gin.Context) {
|
||||
var req RegisterRequest
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, gin.H{"error": "请求参数错误"})
|
||||
return
|
||||
}
|
||||
|
||||
user, err := c.userRepo.CreateUser(req.Username, req.Password)
|
||||
if err != nil {
|
||||
c.logger.Error("创建用户失败: " + err.Error())
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "创建用户失败"})
|
||||
return
|
||||
}
|
||||
|
||||
response := RegisterResponse{
|
||||
ID: user.ID,
|
||||
Username: user.Username,
|
||||
CreatedAt: user.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, gin.H{
|
||||
"message": "用户创建成功",
|
||||
"user": response,
|
||||
})
|
||||
}
|
||||
|
||||
// LoginRequest 登录请求结构体
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
|
||||
// LoginResponse 登录响应结构体
|
||||
type LoginResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Token string `json:"token"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// Login 用户登录
|
||||
func (c *Controller) Login(ctx *gin.Context) {
|
||||
var req LoginRequest
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, gin.H{"error": "请求参数错误"})
|
||||
return
|
||||
}
|
||||
|
||||
// 查找用户
|
||||
user, err := c.userRepo.FindByUsername(req.Username)
|
||||
if err != nil {
|
||||
c.logger.Error("查找用户失败: " + err.Error())
|
||||
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "用户名或密码错误"})
|
||||
return
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(req.Password))
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "用户名或密码错误"})
|
||||
return
|
||||
}
|
||||
|
||||
// 生成JWT访问令牌
|
||||
authMiddleware := middleware.NewAuthMiddleware(c.userRepo)
|
||||
token, err := authMiddleware.GenerateToken(user.ID, user.Username)
|
||||
if err != nil {
|
||||
c.logger.Error("生成令牌失败: " + err.Error())
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "登录失败"})
|
||||
return
|
||||
}
|
||||
|
||||
response := LoginResponse{
|
||||
ID: user.ID,
|
||||
Username: user.Username,
|
||||
Token: token,
|
||||
CreatedAt: user.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, gin.H{
|
||||
"message": "登录成功",
|
||||
"user": response,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user