jdysya 2da6933e00 fix(auth): 修复登录状态检查和退出登录功能
- 优化登录状态检查逻辑,未登录时重定向到登录页
- 添加原目标页面作为登录后返回参数
- 退出登录时清除缓存,确保安全退出
- 移除文档页面的权限校验中间件
2025-02-16 22:51:25 +08:00

205 lines
5.0 KiB
Go

package handlers
import (
"net/http"
"strconv"
"strings"
"gateway/config"
"gateway/models"
"gateway/utils"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"golang.org/x/crypto/bcrypt"
)
func GetLogin(c *gin.Context) {
returnURL := c.Query("return_url")
c.HTML(http.StatusOK, "login.html", gin.H{
"return_url": returnURL,
})
}
func PostLogin(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
returnURL := c.PostForm("return_url")
var user models.User
if err := db.Where("mobile = ?", username).First(&user).Error; err != nil {
c.HTML(http.StatusUnauthorized, "login.html", gin.H{
"error": "用户不存在或密码错误",
"return_url": returnURL,
})
return
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
c.HTML(http.StatusUnauthorized, "login.html", gin.H{
"error": "用户不存在或密码错误",
"return_url": returnURL,
})
return
}
session := sessions.Default(c)
session.Set("user", user.ID)
if err := session.Save(); err != nil {
utils.Logger.Errorf("Session保存失败: %v", err)
c.HTML(http.StatusInternalServerError, "login.html", gin.H{
"error": "登录状态保存失败",
"return_url": returnURL,
})
return
}
if returnURL != "" {
c.Redirect(http.StatusSeeOther, returnURL)
return
}
c.Redirect(http.StatusSeeOther, "/")
}
}
func GetRegister(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
regions, err := getRegions(db)
if err != nil {
c.HTML(http.StatusInternalServerError, "register.html", gin.H{"error": "系统错误"})
return
}
c.HTML(http.StatusOK, "register.html", gin.H{"regions": regions})
}
}
func PostRegister(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
regionStr, exists := c.GetPostForm("region")
if !exists {
handleRegisterError(c, db, "请选择所在地区")
return
}
regionID, err := strconv.ParseUint(regionStr, 10, 32)
if err != nil {
handleRegisterError(c, db, "无效的地区参数")
return
}
user := models.User{
FullName: c.PostForm("fullname"),
Mobile: c.PostForm("mobile"),
RegionID: uint(regionID),
}
var region models.Region
if err := db.First(&region, user.RegionID).Error; err != nil {
handleRegisterError(c, db, "请选择有效地区")
return
}
if len(user.Mobile) != 11 {
handleRegisterError(c, db, "手机号格式不正确")
return
}
password := c.PostForm("password")
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
utils.Logger.Errorf("密码加密失败: %v", err)
handleRegisterError(c, db, "注册失败")
return
}
user.Password = string(hashedPassword)
if err := db.Create(&user).Error; err != nil {
utils.Logger.Errorf("用户创建失败: %v", err)
errorMsg := "注册失败"
if strings.Contains(err.Error(), "UNIQUE constraint failed") {
errorMsg = "该手机号已注册"
}
handleRegisterError(c, db, errorMsg)
return
}
c.Redirect(http.StatusSeeOther, "/login")
}
}
func Logout(c *gin.Context) {
session := sessions.Default(c)
// 使用配置中的session选项
session.Options(config.GetLogoutSessionOptions())
// 清除session数据
session.Clear()
// 添加清除缓存的 HTTP 头
c.Header("Cache-Control", "no-cache, no-store, must-revalidate")
c.Header("Pragma", "no-cache")
c.Header("Expires", "0")
// 保存更改
if err := session.Save(); err != nil {
utils.Logger.Errorf("退出登录失败: %v", err)
c.HTML(http.StatusInternalServerError, "error.html", gin.H{"error": "退出登录失败"})
return
}
c.Redirect(http.StatusSeeOther, "/login")
}
func getRegions(db *gorm.DB) ([]models.Region, error) {
var regions []models.Region
if err := db.Find(&regions).Error; err != nil {
utils.Logger.Errorf("获取地区数据失败: %v", err)
return nil, err
}
return regions, nil
}
func handleRegisterError(c *gin.Context, db *gorm.DB, errorMessage string) {
regions, err := getRegions(db)
if err != nil {
c.HTML(http.StatusInternalServerError, "register.html", gin.H{"error": "系统错误"})
return
}
c.HTML(http.StatusBadRequest, "register.html", gin.H{
"error": errorMessage,
"regions": regions,
"form": gin.H{
"fullname": c.PostForm("fullname"),
"mobile": c.PostForm("mobile"),
},
})
}
func GetUserInfo(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
session := sessions.Default(c)
userID := session.Get("user")
if userID == nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
var user models.User
if err := db.First(&user, userID).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户信息失败"})
return
}
c.JSON(http.StatusOK, gin.H{
"id": user.ID,
"fullName": user.FullName,
"mobile": user.Mobile,
})
}
}