JWT无法撤回问解决

1.在用户User表新加一个字段JWTVersions设置为long类型。

2.用户每登陆一次JWTVersion自动加一,并保存在数据库中且加入到jwt生成的token中;代码如下:

public async Task<ResultApi> Login(string username, string pwd)
        {
            User user =await userService.FindAsync(username);
           
            user.Password = pwd;
            if(user == null|| user.Password != pwd)
            {
                return  ResultHelper.Error("用户名或密码错误");
            }
            else
            {
                user.JWTVersion++;
                userService.EditByEntity(user);//保存到数据库中
                return ResultHelper.Success(customJWTService.GetJwtToken(user));
            }
        }

在jwt生成中:加入JWTversion

...     

     UserRoleRelation userRoleRelation = userRoleService.FindAny(user.Id);
            Role role = roleService.Find(userRoleRelation.RoleId);
            string roleName = role.Name;

            //payload
            var claims = new Claim[]
                {
                    
                    new Claim("Id", user.Id.ToString()),
                    new Claim("Name",user.Name),
                    new Claim("PhoneNumber", user.PhoneNumber),
                    new Claim(ClaimTypes.Role,roleName),
                    new Claim("IsEnable", user.IsEnable.ToString()),
                    new Claim(ClaimTypes.Version,user.JWTVersion.ToString())

                };

 ...

3.添加行为拦截器判断当前用户jwtversion与数据中jwtversion大小,如果数据的jwtversion大于当初用户,则用户登陆失效。

public class JWTValidationFilter : IAsyncActionFilter
    {
        private readonly UserService userService;
        private readonly IMemoryCache cache;

        public JWTValidationFilter(IMemoryCache cache, UserService userService)
        {
            this.cache = cache;
            this.userService = userService;
    }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var value = context.HttpContext.User.FindFirst("id");
            if (value == null)
            {
                await next();
                return;
            }
            Guid id =new Guid(value.Value);
            string chacheKey = $"JWTVaildationFilter.UserInfo.{id}";
            Model.Entitys.User user = await cache.GetOrCreateAsync(chacheKey, async e =>
            {
                e.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(5);
                return  userService.Find(id);
            });
            if (user == null)
            {
                var result = new ObjectResult($"UserId{id} not found");
                result.StatusCode = (int)HttpStatusCode.Unauthorized;
                context.Result=result;
                return;
            }
            var claimVersion = context.HttpContext.User.FindFirst(ClaimTypes.Version);
            long jwtVerOfReq = long.Parse(claimVersion!.Value);
            if (jwtVerOfReq >= user.JWTVersion)
            {
                await next();
            }
            else
            {
                var result = new ObjectResult($"jwtversion mismatch,如:在其他地方登录");
                result.StatusCode = (int)HttpStatusCode.Unauthorized;
                context.Result = result;
                return;
            }
        }

}

4.在program注册服务

builder.Service.Configure<MvcOptions>(op =>{

        op.Filters.Add<>();

});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值