mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-11-08 02:03:42 +08:00
fix: replace session handler with jwt authorization
This commit is contained in:
@@ -8,9 +8,11 @@ import (
|
||||
"chatplus/store/model"
|
||||
"chatplus/utils"
|
||||
"chatplus/utils/resp"
|
||||
"context"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
@@ -20,11 +22,12 @@ var logger = logger2.GetLogger()
|
||||
|
||||
type ManagerHandler struct {
|
||||
handler.BaseHandler
|
||||
db *gorm.DB
|
||||
db *gorm.DB
|
||||
redis *redis.Client
|
||||
}
|
||||
|
||||
func NewAdminHandler(app *core.AppServer, db *gorm.DB) *ManagerHandler {
|
||||
h := ManagerHandler{db: db}
|
||||
func NewAdminHandler(app *core.AppServer, db *gorm.DB, client *redis.Client) *ManagerHandler {
|
||||
h := ManagerHandler{db: db, redis: client}
|
||||
h.App = app
|
||||
return &h
|
||||
}
|
||||
@@ -38,13 +41,22 @@ func (h *ManagerHandler) Login(c *gin.Context) {
|
||||
}
|
||||
manager := h.App.Config.Manager
|
||||
if data.Username == manager.Username && data.Password == manager.Password {
|
||||
err := utils.SetLoginAdmin(c, manager)
|
||||
// 创建 token
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"user_id": manager.Username,
|
||||
"expired": time.Now().Add(time.Second * time.Duration(h.App.Config.Session.MaxAge)),
|
||||
})
|
||||
tokenString, err := token.SignedString([]byte(h.App.Config.Session.SecretKey))
|
||||
if err != nil {
|
||||
resp.ERROR(c, "Save session failed")
|
||||
resp.ERROR(c, "Failed to generate token, "+err.Error())
|
||||
return
|
||||
}
|
||||
manager.Password = "" // 清空密码]
|
||||
resp.SUCCESS(c, manager)
|
||||
// 保存到 redis
|
||||
if _, err := h.redis.Set(context.Background(), "users/"+manager.Username, tokenString, 0).Result(); err != nil {
|
||||
resp.ERROR(c, "error with save token: "+err.Error())
|
||||
return
|
||||
}
|
||||
resp.SUCCESS(c, tokenString)
|
||||
} else {
|
||||
resp.ERROR(c, "用户名或者密码错误")
|
||||
}
|
||||
@@ -52,11 +64,9 @@ func (h *ManagerHandler) Login(c *gin.Context) {
|
||||
|
||||
// Logout 注销
|
||||
func (h *ManagerHandler) Logout(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
session.Delete(types.SessionAdmin)
|
||||
err := session.Save()
|
||||
if err != nil {
|
||||
resp.ERROR(c, "Save session failed")
|
||||
token := c.GetHeader(types.AdminAuthHeader)
|
||||
if _, err := h.redis.Del(c, token).Result(); err != nil {
|
||||
logger.Error("error with delete session: ", err)
|
||||
} else {
|
||||
resp.SUCCESS(c)
|
||||
}
|
||||
@@ -64,9 +74,8 @@ func (h *ManagerHandler) Logout(c *gin.Context) {
|
||||
|
||||
// Session 会话检测
|
||||
func (h *ManagerHandler) Session(c *gin.Context) {
|
||||
session := sessions.Default(c)
|
||||
admin := session.Get(types.SessionAdmin)
|
||||
if admin == nil {
|
||||
token := c.GetHeader(types.AdminAuthHeader)
|
||||
if token == "" {
|
||||
resp.NotAuth(c)
|
||||
} else {
|
||||
resp.SUCCESS(c)
|
||||
|
||||
@@ -3,7 +3,7 @@ package handler
|
||||
import (
|
||||
"chatplus/core"
|
||||
logger2 "chatplus/logger"
|
||||
"strconv"
|
||||
"chatplus/utils"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -20,47 +20,23 @@ func (h *BaseHandler) GetTrim(c *gin.Context, key string) string {
|
||||
}
|
||||
|
||||
func (h *BaseHandler) PostInt(c *gin.Context, key string, defaultValue int) int {
|
||||
return intValue(c.PostForm(key), defaultValue)
|
||||
return utils.IntValue(c.PostForm(key), defaultValue)
|
||||
}
|
||||
|
||||
func (h *BaseHandler) GetInt(c *gin.Context, key string, defaultValue int) int {
|
||||
return intValue(c.Query(key), defaultValue)
|
||||
}
|
||||
|
||||
func intValue(str string, defaultValue int) int {
|
||||
value, err := strconv.Atoi(str)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
return utils.IntValue(c.Query(key), defaultValue)
|
||||
}
|
||||
|
||||
func (h *BaseHandler) GetFloat(c *gin.Context, key string) float64 {
|
||||
return floatValue(c.Query(key))
|
||||
return utils.FloatValue(c.Query(key))
|
||||
}
|
||||
func (h *BaseHandler) PostFloat(c *gin.Context, key string) float64 {
|
||||
return floatValue(c.PostForm(key))
|
||||
}
|
||||
|
||||
func floatValue(str string) float64 {
|
||||
value, err := strconv.ParseFloat(str, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return value
|
||||
return utils.FloatValue(c.PostForm(key))
|
||||
}
|
||||
|
||||
func (h *BaseHandler) GetBool(c *gin.Context, key string) bool {
|
||||
return boolValue(c.Query(key))
|
||||
return utils.BoolValue(c.Query(key))
|
||||
}
|
||||
func (h *BaseHandler) PostBool(c *gin.Context, key string) bool {
|
||||
return boolValue(c.PostForm(key))
|
||||
}
|
||||
|
||||
func boolValue(str string) bool {
|
||||
value, err := strconv.ParseBool(str)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return value
|
||||
return utils.BoolValue(c.PostForm(key))
|
||||
}
|
||||
|
||||
@@ -9,10 +9,12 @@ import (
|
||||
"chatplus/store/vo"
|
||||
"chatplus/utils"
|
||||
"chatplus/utils/resp"
|
||||
"fmt"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
"gorm.io/gorm"
|
||||
@@ -23,6 +25,7 @@ type UserHandler struct {
|
||||
db *gorm.DB
|
||||
searcher *xdb.Searcher
|
||||
leveldb *store.LevelDB
|
||||
redis *redis.Client
|
||||
uploadManager *oss.UploaderManager
|
||||
}
|
||||
|
||||
@@ -31,8 +34,9 @@ func NewUserHandler(
|
||||
db *gorm.DB,
|
||||
searcher *xdb.Searcher,
|
||||
levelDB *store.LevelDB,
|
||||
client *redis.Client,
|
||||
manager *oss.UploaderManager) *UserHandler {
|
||||
handler := &UserHandler{db: db, searcher: searcher, leveldb: levelDB, uploadManager: manager}
|
||||
handler := &UserHandler{db: db, searcher: searcher, leveldb: levelDB, redis: client, uploadManager: manager}
|
||||
handler.App = app
|
||||
return handler
|
||||
}
|
||||
@@ -122,7 +126,7 @@ func (h *UserHandler) Register(c *gin.Context) {
|
||||
// Login 用户登录
|
||||
func (h *UserHandler) Login(c *gin.Context) {
|
||||
var data struct {
|
||||
Username string `json:"mobile"`
|
||||
Mobile string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&data); err != nil {
|
||||
@@ -130,7 +134,7 @@ func (h *UserHandler) Login(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
var user model.User
|
||||
res := h.db.Where("mobile = ?", data.Username).First(&user)
|
||||
res := h.db.Where("mobile = ?", data.Mobile).First(&user)
|
||||
if res.Error != nil {
|
||||
resp.ERROR(c, "用户名不存在")
|
||||
return
|
||||
@@ -152,13 +156,6 @@ func (h *UserHandler) Login(c *gin.Context) {
|
||||
user.LastLoginAt = time.Now().Unix()
|
||||
h.db.Model(&user).Updates(user)
|
||||
|
||||
err := utils.SetLoginUser(c, user)
|
||||
if err != nil {
|
||||
resp.ERROR(c, "保存会话失败")
|
||||
logger.Error("Error for save session: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
h.db.Create(&model.UserLoginLog{
|
||||
UserId: user.Id,
|
||||
Username: user.Mobile,
|
||||
@@ -166,17 +163,32 @@ func (h *UserHandler) Login(c *gin.Context) {
|
||||
LoginAddress: utils.Ip2Region(h.searcher, c.ClientIP()),
|
||||
})
|
||||
|
||||
resp.SUCCESS(c)
|
||||
// 创建 token
|
||||
expired := time.Now().Add(time.Second * time.Duration(h.App.Config.Session.MaxAge))
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"user_id": user.Id,
|
||||
"expired": expired,
|
||||
})
|
||||
tokenString, err := token.SignedString([]byte(h.App.Config.Session.SecretKey))
|
||||
if err != nil {
|
||||
resp.ERROR(c, "Failed to generate token, "+err.Error())
|
||||
return
|
||||
}
|
||||
// 保存到 redis
|
||||
key := fmt.Sprintf("users/%d", user.Id)
|
||||
if _, err := h.redis.Set(c, key, tokenString, 0).Result(); err != nil {
|
||||
resp.ERROR(c, "error with save token: "+err.Error())
|
||||
return
|
||||
}
|
||||
resp.SUCCESS(c, tokenString)
|
||||
}
|
||||
|
||||
// Logout 注 销
|
||||
func (h *UserHandler) Logout(c *gin.Context) {
|
||||
sessionId := c.GetHeader(types.SessionName)
|
||||
session := sessions.Default(c)
|
||||
session.Delete(types.SessionUser)
|
||||
err := session.Save()
|
||||
if err != nil {
|
||||
logger.Error("Error for save session: ", err)
|
||||
sessionId := c.GetHeader(types.ChatTokenHeader)
|
||||
token := c.GetHeader(types.UserAuthHeader)
|
||||
if _, err := h.redis.Del(c, token).Result(); err != nil {
|
||||
logger.Error("error with delete session: ", err)
|
||||
}
|
||||
// 删除 websocket 会话列表
|
||||
h.App.ChatSession.Delete(sessionId)
|
||||
|
||||
Reference in New Issue
Block a user