欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.net core使用jwt自动续期

程序员文章站 2022-06-19 19:21:19
小弟不C才,最近看了下网上的jwt方案,于是自己写了一个简单的jwt方案和大家分享下,希望大家给点意见! 假如有一个读书网站,可以不用登陆就访问,当需要自己写文章的时候就必须登录,并且登录之后如果一段时间内没有访问,则过期了需要重新登录。有效期内有登录则自动续期,所以我想使用中间件来负责token的 ......

           小弟不c才,最近看了下网上的jwt方案,于是自己写了一个简单的jwt方案和大家分享下,希望大家给点意见!

           假如有一个读书网站,可以不用登陆就访问,当需要自己写文章的时候就必须登录,并且登录之后如果一段时间内没有访问,则过期了需要重新登录。有效期内有登录则自动续期,所以我想使用中间件来负责token的更新以及删除。如下部分代码:

     

      public async task invokeasync(httpcontext context)
        {
            try
            {
                bool isexpires = context.request.headers.trygetvalue("isexpires", out stringvalues expires);
                bool isauthorized = context.request.headers.trygetvalue("authorization", out stringvalues authstr);
                string token = authstr.tostring().substring("bearer ".length).trim();
                //每次访问都更新token有效期
                new jwt(_cacheclient).refreshtoken(token, isexpires);
                context.response.headers.add("refreshtokne", token);
            }
            catch (validationexception)
            {
                if (context.request.path.value.contains("api/auth/islogin"))
                {
                    context.response.contenttype = "text/plain";
                    await context.response.writeasync("not login");
                }
            }
              await _next(context);
        }

        /// <summary>
        /// 生成jwttoken,有效期30分钟
        /// </summary>
        /// <param name="claims"></param>
        /// <returns></returns>
        public static string createtoken(ienumerable<claim> claims)
        {
            var key = new symmetricsecuritykey(system.text.encoding.utf8.getbytes(securitykey));
            var expires = datetime.now.addminutes(30);
            var token = new jwtsecuritytoken(
                        issuer: issuer,
                        audience: audience,
                        claims: claims,
                        notbefore: datetime.now,
                        expires: expires,
                        signingcredentials: new signingcredentials(key, securityalgorithms.hmacsha256signature));
            string jwttoken = new jwtsecuritytokenhandler().writetoken(token);
            return jwttoken;
        }
        /// <summary>
        /// 更新token,先通过前端传过来的token从redis里取出jwt,如果为null,则表 
        ///示过期或未登录,如果jwt过期,则更新jwt,并且通过中间件把新的token放到响应头里返回前端。
        /// </summary>
        /// <param name="token">token</param>
        /// <param name="isexpires">是否失效</param>
        public  void refreshtoken(string token,bool isexpires=false)
        {

            tokenmodel tokenmode = _cacheclient.get<tokenmodel>(token);
            if (tokenmode == null)
                throw new validationexception("expires");
            jwtsecuritytoken jwtsecuritytoken= new jwtsecuritytokenhandler().readjwttoken(token);
            if(isexpires)
                token = createtoken(jwtsecuritytoken.claims);
            tokenmode.expiretime = tokenmode.expiretime.adddays(7);
            if(tokenmode.expiretime.day-datetime.now.day==1)//实现最后一天如果访问了就自动续期
                _cacheclient.set(token, tokenmode, timespan.fromdays(7));

        }

  然后前端可以根据响应结果来判断是否跳到登录页。