| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- // Code scaffolded by goctl. Safe to edit.
- // goctl 1.10.0
- package auth
- import (
- "context"
- "errors"
- "fmt"
- "perms-system-server/internal/middleware"
- userModel "perms-system-server/internal/model/user"
- "perms-system-server/internal/response"
- "perms-system-server/internal/svc"
- "github.com/zeromicro/go-zero/core/limit"
- "github.com/zeromicro/go-zero/core/logx"
- )
- type LogoutLogic struct {
- logx.Logger
- ctx context.Context
- svcCtx *svc.ServiceContext
- }
- func NewLogoutLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LogoutLogic {
- return &LogoutLogic{
- Logger: logx.WithContext(ctx),
- ctx: ctx,
- svcCtx: svcCtx,
- }
- }
- // Logout 用户注销。递增当前用户的 tokenVersion 使所有已签发的 access/refresh 令牌立即失效,并清除用户缓存。
- func (l *LogoutLogic) Logout() error {
- userId := middleware.GetUserId(l.ctx)
- if userId == 0 {
- return response.ErrUnauthorized("未登录")
- }
- if l.svcCtx.TokenOpLimiter != nil {
- code, _ := l.svcCtx.TokenOpLimiter.Take(fmt.Sprintf("logout:%d", userId))
- if code == limit.OverQuota {
- return response.ErrTooManyRequests("操作过于频繁,请稍后再试")
- }
- }
- if _, err := l.svcCtx.SysUserModel.IncrementTokenVersion(l.ctx, userId); err != nil {
- // 审计 L-R10-3:IncrementTokenVersion 在目标用户已被并发删除时会返 ErrUpdateConflict。
- // Logout 的语义目标本就是"让该账号的旧令牌立即失效",用户已经消失等同语义已达成,
- // 按幂等成功处理并继续清缓存,不要让一次正常的注销因为极罕见的删号竞态回 500。
- if !errors.Is(err, userModel.ErrUpdateConflict) {
- return err
- }
- logx.WithContext(l.ctx).Infof("logout on already-deleted user userId=%d, treated as idempotent success", userId)
- }
- l.svcCtx.UserDetailsLoader.Clean(l.ctx, userId)
- return nil
- }
|