在 asp net core MVC 应用程序中创建和验证 JWT 令牌(没有客户端服务器方法)

Posted

技术标签:

【中文标题】在 asp net core MVC 应用程序中创建和验证 JWT 令牌(没有客户端服务器方法)【英文标题】:Creating and validating JWT token in asp net core MVC application (which does not have client server approach) 【发布时间】:2021-02-28 10:09:12 【问题描述】:

我见过很多在 WEP API 中生成和验证 JWT 令牌的示例。

WEP API 将有客户端和服务器的方法。因此,我们将验证用户并在服务器中生成 JWT 令牌并发送到客户端。客户端下次通过httpclient将令牌存储在浏览器内存中,令牌将附加在请求头中并再次发送给服务器。现在服务器将在点击控制器之前验证这些令牌并允许访问这些资源。

但是在 MVC 应用程序中,我们没有客户端和服务器的方法。它会将视图页面作为结果发送到浏览器。

我的问题是在 MVC 控制器中我已经验证了用户并创建了 JWT 令牌,

    现在如何在客户端存储令牌 如何在请求标头中附加令牌。 在 MVC 中我应该在哪里执行令牌验证逻辑。 在 MVC 中我应该在哪里执行刷新令牌逻辑。

提前致谢

【问题讨论】:

【参考方案1】:

根据您的问题,这里有几种解决方案。

    将令牌存储在 cookie 中,这是推荐的做法。示例:

         services.AddAuthentication(x =>
         
             x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
             x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
         )
             .AddCookie(config=>
             
                 config.Cookie.Name = "auth";
             )
         .AddJwtBearer(o =>
         
             o.TokenValidationParameters = new TokenValidationParameters
             
                 NameClaimType = JwtClaimTypes.Name,
                 //...
             ;
         );
    

虽然后端可以序列化令牌并发送到视图(使用 javascript 将令牌存储在 Localstorage 中),但这并不安全。 Cookie 可以避免 csrf 攻击。适合单页应用。

    如果放在LocalStorage或SessionStorage中,需要先拿到token,放在请求的header中(以ajax为例)。否则,无需其他配置。
发送前:函数(请求) request.setRequestHeader("授权", sessionStorage.getItem("授权"));

    您需要在某些操作中添加[Authorize],它将触发您在服务中配置的此身份验证。或者您可以添加一个动作来解析令牌以获取上下文。

    当有人更新自己的信息时,您可以重新生成一个令牌,然后将其发送到视图以更新 LocalStorage 或 cookie。它将在下一个请求中携带此令牌。

视图可以发送验证请求。

public IActionResult Authenticate()
    
        //...
        var token = tokenHandler.CreateToken(tokenDescriptor);
        var tokenString = tokenHandler.WriteToken(token);
        Response.Cookies.Append("authname", tokenString);
        return View("index");
    

在启动(ConfigureServices)中,你可以用cookie配置获取方法。

services.AddAuthentication(x =>
        
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        )
            .AddCookie(config=>
            
                config.Cookie.Name = "authname";
            )
  .AddJwtBearer(o =>
  
   o.Events = new JwtBearerEvents()
   
       //get cookie value
       OnMessageReceived = context =>
       
           var a = "";
           context.Request.Cookies.TryGetValue("authname", out a);
           context.Token = a;
           return Task.CompletedTask;
       
   ;
   o.TokenValidationParameters = new TokenValidationParameters
   
       NameClaimType = JwtClaimTypes.Name,
       RoleClaimType = JwtClaimTypes.Role,

       ValidIssuer = "http://localhost:5200",
       ValidAudience = "api",
       IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("this is a long key------------------------"))
       //...
    ;
 );

【讨论】:

感谢您的回答。是否可以在没有 ajax 调用的情况下在刷新标头中添加令牌,并且我需要检查令牌是否已过期并发出新令牌。是来自任何中间件还是如何? 是的,您可以在没有 ajax 调用的情况下将令牌添加到刷新标头中。服务器会根据中间件自动进行验证。您可以自定义一个中间件来解析令牌并比较过期时间。更好的方案是视图发起请求,后端验证token是否过期;如果过期,视图会发起令牌刷新请求。 是否有任何示例可用于在请求标头中添加令牌。和没有 web api 和 ajax 的 JWT MVC 示例 这个link可以帮助你。我在这个答案中更新了设置cookie的方法。

以上是关于在 asp net core MVC 应用程序中创建和验证 JWT 令牌(没有客户端服务器方法)的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.NET MVC 迁移到 ASP.NET Core MVC

将 jQuery JSON 对象保存到 SQL 表中,而无需在 MVC ASP.NET Core 中创建视图模型类

如何在 ASP.Net Core MVC 中使用 HTML 链接?

使用日期时间选择器进行日期和时间验证 (ASP.Net MVC Core v1.1)

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)

在 IIS 上使用 .NET Core 运行 ASP.NET 5 (MVC 6)