110 lines
3.0 KiB
Go
110 lines
3.0 KiB
Go
|
package app
|
|||
|
|
|||
|
import (
|
|||
|
"Lee-WineList/client"
|
|||
|
"Lee-WineList/common/constant"
|
|||
|
"Lee-WineList/core"
|
|||
|
"Lee-WineList/model/param"
|
|||
|
"Lee-WineList/oauth2"
|
|||
|
"Lee-WineList/repository"
|
|||
|
"context"
|
|||
|
"encoding/json"
|
|||
|
"fmt"
|
|||
|
"git.echol.cn/loser/logger/log"
|
|||
|
"github.com/gin-gonic/gin"
|
|||
|
"net/http"
|
|||
|
"net/url"
|
|||
|
)
|
|||
|
|
|||
|
type loginApi struct{}
|
|||
|
|
|||
|
// LoginApi 暴露接口
|
|||
|
func LoginApi() *loginApi {
|
|||
|
return &loginApi{}
|
|||
|
}
|
|||
|
|
|||
|
// Login 登录
|
|||
|
func (l loginApi) Login(ctx *gin.Context) {
|
|||
|
var p param.Login
|
|||
|
if err := ctx.ShouldBind(&p); err != nil {
|
|||
|
core.R(ctx).FailWithMessage(err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// 获取用户基础账号信息
|
|||
|
userId, err := oauth2.OAuthServer.UserAuthorizationHandler(ctx.Writer, ctx.Request)
|
|||
|
if err != nil {
|
|||
|
log.Errorf("获取用户基础账号信息失败: %v", err)
|
|||
|
core.R(ctx).FailWithMessage(err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
// 重新组装登录参数
|
|||
|
ctx.Request.Form = url.Values{
|
|||
|
"username": {userId},
|
|||
|
"password": {p.Password},
|
|||
|
"scope": {"ALL"},
|
|||
|
"grant_type": {"password"},
|
|||
|
}
|
|||
|
|
|||
|
// 参数解析成功,进行登录
|
|||
|
if err = oauth2.OAuthServer.HandleTokenRequest(ctx.Writer, ctx.Request); err != nil {
|
|||
|
log.Errorf("登录失败:%s", err.Error())
|
|||
|
core.R(ctx).FailWithMessage("系统错误,登录失败")
|
|||
|
return
|
|||
|
}
|
|||
|
// 登录成功才更新登录时间
|
|||
|
if ctx.Writer.Status() == http.StatusOK {
|
|||
|
// 登录成功,更新登录时间和IP
|
|||
|
go repository.Login().UpdateLastLoginInfo(userId, ctx.ClientIP(), p.UserIdentity)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Refresh 刷新登录Token
|
|||
|
func (loginApi) Refresh(ctx *gin.Context) {
|
|||
|
var p param.RefreshToken
|
|||
|
if err := ctx.ShouldBind(&p); err != nil {
|
|||
|
core.R(ctx).FailWithMessage("参数错误: " + err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// 刷新Token
|
|||
|
if err := oauth2.OAuthServer.HandleTokenRequest(ctx.Writer, ctx.Request); err != nil {
|
|||
|
log.Errorf("Token数据返回失败: %v", err.Error())
|
|||
|
core.R(ctx).FailWithMessage("系统错误")
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Logout 退出登录
|
|||
|
func (loginApi) Logout(ctx *gin.Context) {
|
|||
|
log.Debug("退出登录啦")
|
|||
|
r := core.R(ctx)
|
|||
|
// Token字符串前缀
|
|||
|
const bearerSchema string = "Bearer "
|
|||
|
// 取出Token
|
|||
|
tokenHeader := ctx.Request.Header.Get("Authorization")
|
|||
|
tokenStr := tokenHeader[len(bearerSchema):]
|
|||
|
// 取出原始RedisKey
|
|||
|
baseDataId, err := client.Redis.Get(context.Background(), constant.OAuth2RedisKey+tokenStr).Result()
|
|||
|
if err != nil {
|
|||
|
r.FailWithMessage("Token信息获取失败")
|
|||
|
return
|
|||
|
}
|
|||
|
baseDataStr, err := client.Redis.Get(context.Background(), constant.OAuth2RedisKey+baseDataId).Result()
|
|||
|
if err != nil {
|
|||
|
r.FailWithMessage("Token信息获取失败")
|
|||
|
return
|
|||
|
}
|
|||
|
// 转换数据为Map
|
|||
|
tokenData := make(map[string]any)
|
|||
|
if err = json.Unmarshal([]byte(baseDataStr), &tokenData); err != nil {
|
|||
|
r.FailWithMessage("系统错误: " + err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
// 删除Redis缓存的数据
|
|||
|
client.Redis.Del(context.Background(), constant.OAuth2RedisKey+baseDataId)
|
|||
|
client.Redis.Del(context.Background(), fmt.Sprintf("%v%v", constant.OAuth2RedisKey, tokenData["Access"]))
|
|||
|
client.Redis.Del(context.Background(), fmt.Sprintf("%v%v", constant.OAuth2RedisKey, tokenData["Refresh"]))
|
|||
|
|
|||
|
r.Ok()
|
|||
|
}
|