Lee-WineList/api/app/login.go
2023-04-24 17:19:41 +08:00

110 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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