You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.0 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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()
}