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