• 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、代码实现

    添加自定义认证代码:

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

    设置JWT的认证参数: 

    1. public static JWTSettingsOptions SetValidParameter()
    2. {
    3. JWTSettingsOptions options = new JWTSettingsOptions()
    4. {
    5. ValidateIssuerSigningKey = true,
    6. IssuerSigningKey = App.Configuration["JWTSettings:IssuerSigningKey"],
    7. ValidateIssuer = true,
    8. ValidIssuer = App.Configuration["JWTSettings:ValidIssuer"],
    9. ValidateAudience = true,
    10. ValidAudience = App.Configuration["JWTSettings:ValidAudience"],
    11. ValidateLifetime = true,
    12. Algorithm = SecurityAlgorithms.HmacSha256,
    13. ClockSkew = 0
    14. };
    15. return options;
    16. }

     自定义认证:

    1. public class JwtHandler : AppAuthorizeHandler
    2. {
    3. public override async Task HandleAsync(AuthorizationHandlerContext context)
    4. {
    5. if (JWTHelper.AutoRefreshToken(context))
    6. await AuthorizeHandleAsync(context);
    7. else
    8. context.Fail();
    9. }
    10. }

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

    1. public static bool AutoRefreshToken(AuthorizationHandlerContext context)
    2. {
    3. return JWTEncryption.AutoRefreshToken(context,
    4. context.GetCurrentHttpContext());
    5. }

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

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

    JWTEncryption.GenerateRefreshToken(token);

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

    3、填坑

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

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

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

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

  • 相关阅读:
    Chiitoitsu
    HTML+CSS大作业 (水果之家10个网页)
    Android手机保持屏幕常亮
    scikit-learn 中 Boston Housing 数据集问题解决方案
    LiveCharts WPF 实时数据慢。提高 LiveCharts 实时绘图性能
    MONGODB 的基础 NOSQL注入基础
    SPA项目开发之登陆注册
    低代码如何增强团队应用开发能力?
    测试维表的更新
    跨越编程界限:C++到JavaSE的平滑过渡
  • 原文地址:https://blog.csdn.net/niechaoya/article/details/126528320