ASP.NET CORE JWT 双token刷新认证

我所使用的环境如下:

ASP.NET CORE 6.0

Furion 3.7.5

可能有些人还不知道这个Furion是什么东西,这里给出它的开发文档的连接,有兴趣的朋友可以了解一下这个框架。这个框架是对ASP.NET CORE框架的一个封装,使用起来挺方便的,值得推荐给大家。

开发文档链接:1.1 介绍 | Furion

参考:15. 安全鉴权 | Furion

1、什么是双token刷新认证

一般情况下我们使用一个token来认证,但是这样的话有一个问题:服务端生成的token的有效期是固定的,默认20分钟。当用户在界面上操作了20分钟以后,这个token就失效了,系统会返回401认证失败,这个情况在我看来是不太合理的。比如用户在执行添加操作,在提交的时候告诉你认证失败了,重新登录后之前添加的内容就要重新写一次,那他肯定要抓狂了,嘴里骂着这是什么烂软件。

刷新token的有效期默认是30天,可以自定义

当我们用2个token来认证的时候,流程是这样的:用户登录成功后,返回2个token,一个是正常的token,一个是刷新token。每次请求时都带上这2个token(其实刷新token不用每次携带,只在正常token快失效的携带就可以了,这里需要前端做一个判断,如果前端不愿意判断,每次都携带也可以,只是多耗费一点流量罢了)。当token有效期过了,系统会判断有效期超过的时间是不是大于刷新token的有效期,如果大于就返回401(因为刷新token的有效期很长,所以这种情况基本不会发生,你添加一个数据会用30天吗?),反之则会刷新正常的token,把正常token的有效期延长,刷新token的有效期也会相应的延长。然后把这2个新token放到http的返回头里面,前端接收到这2个新的token之后,替换之前的token。

2、代码实现

添加自定义认证代码:

var jwtSetOption = JWTHelper.SetValidParameter();
builder.Services.AddJwt(null,jwtSetOption);

设置JWT的认证参数: 

public static JWTSettingsOptions SetValidParameter()
        {
            JWTSettingsOptions options = new JWTSettingsOptions()
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = App.Configuration["JWTSettings:IssuerSigningKey"],
                ValidateIssuer = true,
                ValidIssuer = App.Configuration["JWTSettings:ValidIssuer"],
                ValidateAudience = true,
                ValidAudience = App.Configuration["JWTSettings:ValidAudience"],
                ValidateLifetime = true,
                Algorithm = SecurityAlgorithms.HmacSha256,
                ClockSkew = 0
            };
            return options;
        }

 自定义认证:

public class JwtHandler : AppAuthorizeHandler
    {
        public override async Task HandleAsync(AuthorizationHandlerContext context)
        {
            if (JWTHelper.AutoRefreshToken(context))
                await AuthorizeHandleAsync(context);
            else
                context.Fail();
        }
    }

JWTHelper.AutoRefreshToken这个函数是我封装的方法,这个方法的代码如下:

public static bool AutoRefreshToken(AuthorizationHandlerContext context)
        {
            return JWTEncryption.AutoRefreshToken(context,         
            context.GetCurrentHttpContext());
        }

引用的命名空间:using Furion.DataEncryption;

生成刷新token,这个token参数就是调用JWTEncryption.Encrypt函数生成的正常的token,这里可以自定义刷新token的有效期:

JWTEncryption.GenerateRefreshToken(token);

代码就这么几行,但是这里有几个坑要填

3、填坑

1、AddJwt必须在AddControllers之前调用,不然自定义认证的HandleAsync函数就不会被调用。

2、在配置JWT认证参数的时候,参数配置是这样的:

  "JWTSettings": {
    "ValidateIssuerSigningKey": true, // 是否验证密钥,bool 类型,默认true
    "IssuerSigningKey": "", // 密钥,string 类型,必须是复杂密钥,长度大于16
    "ValidateIssuer": true, // 是否验证签发方,bool 类型,默认true
    "ValidIssuer": "", // 签发方,string 类型
    "ValidateAudience": true, // 是否验证签收方,bool 类型,默认true
    "ValidAudience": "", // 签收方,string 类型
    "ValidateLifetime": true, // 是否验证过期时间,bool 类型,默认true,建议true
    "ExpiredTime": 20, // 过期时间,long 类型,单位分钟,默认20分钟
    "ClockSkew": 5, // 过期时间容错值,long 类型,单位秒,默认 5秒
    "Algorithm": "HS256" // 加密算法,string 类型,默认 HS256
  }

这里的参数名字不要去改,因为在JWTEncryption.AutoRefreshToken函数内部会读取这个配置,如果名字改了就读取不到了,读取不到就会使用默认的值。这个时候你可能就会奇怪,明明我在配置文件里配置的过期时间是60分钟,但是生成的新的token的过期时间变成了20分钟。我就是因为手贱改了配置参数的名称才发现了这个问题。

你可能感兴趣的:(ASP.NET,CORE,服务器,运维,ASP.NET,CORE,JWT,双token)