系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 网络编程 > ASP.NET > 详细页面

.net core中使用jwt进行认证

时间:2020-09-06来源:www.pcxitongcheng.com作者:电脑系统城

JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公用/专用密钥对对JWT进行签名。

传统token

当用登录成功后,服务端会根据用户的信息生成一个token,然后将token保存到redis中。当用户再次访问时会携带这个token访问,这时服务端会先去查一下redis,看有没有这个token或者是查看这个token是否过期,当redis中没有这个token时,登录验证失败,提示用户登录失败,否则直接放行。当然传统的token也有其一定的优势,比如说返回token能屏蔽用户的真实信息,临时且唯一。但当并发数量大的时候,这种模式存在的问题就是,用户一访问就去查redis,会增加redis的压力。

JWT

jwt通常由三部分组成分别是:

  • Header
  • Payload
  • Signature

  Header通常由两部分组成,令牌的类型(即JWT)和所使用的签名算法,例如HMAC SHA256或RSA。

{
  "alg": "HS256",
  "typ": "JWT"
}

  Payload 令牌的第二部分是有效负载,其中包含声明。声明是有关实体(通常是用户)和其他数据的声明。有以下三种类型:注册声明,公共声明和私人声明。

  标准注册声明  

  iss:jwt的发行方
  sub:jwt声明的主题
  aud:jwt所面向的群体
  exp:到期时间
  nbf:(不早于)声明标识了JWT之前的时间不得接受处理

  公共声明

    使用JWT的人可以随意定义这些声明。主要包括用户的各种信息但要避免私密的信息

  私密声明

    私有声明是发布者和面向者所共同定义的声明

{
  "phone": "1234567890",
  "name": "John Doe",
  "admin": true
}

  Signature

signature是一个签名信息,是对前两部分进行base64加密和secret一起进行组合加密,这里的secret就相当于一个加盐的操作

例如,如果要使用HMAC SHA256算法,则将通过以下方式创建签名:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

最后生成的token就是下面的这种格式

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoid293byIsInN1YiI6InN1Yk5hbWUiLCJuYmYiOiIxNTk5MzY3NjUwIiwiZXhwIjoxNTk5MzY3OTUwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQ5OTk5IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo0OTk5OSJ9.cqn55T-VFKkKuG2hSdQ_WNqjBhYiK9o3LvK-E9a893Y

通过jwt的工作原理,我们会发现jwt与传统的token相比,jwt不用去redis中查询对应的token信息而是通过定义的加密算法去进行校验,这一块算是对token的重大改进吧

.Net Core中使用JWT

1.通过nuget安装 Microsoft.AspNetCore.Authentication.JwtBearer

2.在ConfigureServices中进行相应的注册

复制代码
      //使用jwt进行认证
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options => {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,  //是否验证超时  当设置exp和nbf时有效 
                        ValidateIssuerSigningKey = true,  ////是否验证密钥
                        ValidAudience = "http://localhost:49999",//Audience
                        ValidIssuer = "http://localhost:49998",//Issuer,这两项和登陆时颁发的一致
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("123456888jdijxhelloworldprefect")),     //拿到SecurityKey
                        //缓冲过期时间,总的有效时间等于这个时间加上jwt的过期时间,如果不配置,默认是5分钟                                                                                                            //注意这是缓冲过期时间,总的有效时间等于这个时间加上jwt的过期时间,如果不配置,默认是5分钟
                        ClockSkew = TimeSpan.FromMinutes(5)   //设置过期时间
                    };
                });
复制代码

2.在Configure中添加认证授权中间件

复制代码
  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseRouting();
            app.UseAuthentication();   //认证
            app.UseAuthorization();    //授权
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
复制代码

3.登录成功后生成token并返回客户端

复制代码
       [HttpPost]
        public IActionResult Login(string username,string password)
        {
            var user = bll.GetUser(username, password);
            if (user != null)
            {
                var claims = new[]
               {
                   new Claim(ClaimTypes.Name,username),
                   new Claim(JwtRegisteredClaimNames.Sub, "subName"),
                   new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),    //NotBefore  token生效时间
                   new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMilliseconds(1)).ToUnixTimeSeconds()}") //Expiration  到期时间,按秒数计算
                };
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("123456888jdijxhelloworldprefect"));   //key的长度要超过16个字符,不然回抛出异常
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                var token = new JwtSecurityToken(
                   issuer: "http://localhost:49999",           //颁发token的web应用程序
                   audience: "http://localhost:49998",
                   claims: claims,
                   expires: DateTime.Now.AddMinutes(5),
                   signingCredentials: creds);
                return Ok(new
                {
                    token = new JwtSecurityTokenHandler().WriteToken(token),success=true,message="登录成功"
                });
            }
            else
            {
                return BadRequest(new { success = false, message = "登录失败,请重试" });
            }
        }
复制代码
用postman进行测试
1.调用登录接口生成token

 

 2.不加token去访问保护的资源

 

 3.带上生成的token再次访问

 

 

分享到:

相关信息

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载