Spaces:
Paused
Paused
File size: 2,699 Bytes
3392510 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
package api
import (
"augment2api/config"
"augment2api/pkg/logger"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
const (
TokenKey = "login:token:"
)
// 生成随机会话令牌
func generateSessionToken() string {
tokenUUID := uuid.New()
return tokenUUID.String()
}
// LoginRequest 登录请求结构
type LoginRequest struct {
Password string `json:"password"`
}
// LoginHandler 处理登录请求
func LoginHandler(c *gin.Context) {
var req LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"status": "error",
"error": "无效的请求数据",
})
return
}
// 验证密码
if req.Password == config.AppConfig.AccessPwd {
// 生成会话令牌
token := generateSessionToken()
// 将会话令牌保存到Redis,有效期24小时
sessionKey := TokenKey + token
err := config.RedisSet(sessionKey, "valid", 24*time.Hour)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"status": "error",
"error": "保存会话失败: " + err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"status": "success",
"token": token,
})
return
}
// 密码错误
c.JSON(http.StatusUnauthorized, gin.H{
"status": "error",
"error": "密码错误",
})
}
// ValidateToken 验证Token
func ValidateToken(token string) bool {
if token == "" {
return false
}
// 检查Redis中是否存在该token
tokenKey := TokenKey + token
exists, err := config.RedisExists(tokenKey)
if err != nil || !exists {
return false
}
return true
}
// AuthTokenMiddleware 会话认证中间件
func AuthTokenMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 如果未设置访问密码,则不需要验证
if config.AppConfig.AccessPwd == "" {
c.Next()
return
}
// 从查询参数或Cookie中获取会话令牌
token := c.GetHeader("X-Auth-Token")
if token == "" {
token = c.Query("token")
}
if token == "" {
token, _ = c.Cookie("auth_token")
}
// 验证会话令牌
if !ValidateToken(token) {
logger.Log.Info("无效的会话令牌:", token)
c.Redirect(http.StatusFound, "/login?error=token_expired")
c.Abort()
return
}
c.Next()
}
}
// LogoutHandler 处理登出请求
func LogoutHandler(c *gin.Context) {
token := c.GetHeader("X-Auth-Token")
if token != "" {
// 从Redis中删除会话token
tokenKey := TokenKey + token
err := config.RedisDel(tokenKey)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"status": "error",
"error": "删除会话失败: " + err.Error(),
})
return
}
}
c.JSON(http.StatusOK, gin.H{
"status": "success",
})
}
|