在.net Core 3.0中使用jwt验证

 

由于工作需要写一个下载文件的api,要求要有jwt token验证,想着正好可以在Core中试试水,下面是整个开发过程;

   由于开始并不懂jwt,在网上找了些相关的资料,对于使用Core api + jwt的文章并不多,这个文章看起来有很多东西:https://www.cnblogs.com/CreateMyself/p/11123023.html,下面是跟着此文章进行的操作,以及自己的一些想法;

 jwt由三部分构成,基本范式是:

  1. {"alg":"HS256","typ":"JWT"}
  2. {"sub":"BY","nbf":1575448305,"exp":1575448905}
  3. 加密串1234567890123456  

详细说明: 

1.第一部分以Base64编码的Header主要包括Token的类型和所使用的算法,我的理解是定义的一个标准模板,基本使用范式即可

2.第二部分以Base64编码的Payload主要包含的是声明(Claims);我的理解是这个地方携带一些用户自定义的信息,但由于jwt的原理(下面会说),第一部分和第二部分使用的加密只是base64的编码转换,不存在加密,所以保存的信息都是次要信息

3.第三部分则是将Key通过对应的加密算法生成签名,最终三部分以点隔开;也就是通过自己的key把上面两部分加密,且这个加密是不可逆的,也就是只会存在前面两部分被修改,或者第三部分被修改,但都会失去自洽性,也就是通过这个验证;

虽然原理说起来简单,但实际操作起来就头大了,下面说下整个过程,

首先,我们先建立一个Core 3.0版的控制台,然后把必要的分层什么的建立起来

在.net Core 3.0中使用jwt验证_第1张图片

基本的分层没什么说的,mvc架构加上连数据库的MongoFactory,定义zip生成和下载方法的Ziphelper,由于不是本节重点,此处不做演示;(tokenHlper请忽略)

下面我们开始考虑加上jwt验证,都知道现在在vs里搞东西第一步就是去拿Nuget包,支持jwt的需要这两个包

System.IdentityModel.Tokens.Jwt和Microsoft.AspNetCore.Authentication.JwtBearer

然后我们需要生成jwt的token

在这我直接在 zipHelper里面写了个GetToken的方法:

在.net Core 3.0中使用jwt验证_第2张图片

public string GetToken()
        {
            var claims = new Claim[]
           {
                new Claim(JwtRegisteredClaimNames.Sub, "BY"),//此处我的理解是用户自定义部分,也就是jwt中第二部分的数据,                                                                                      //JwtRegisteredClaimNames是微软定义的一些key,其实完全可以自定义
           };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234xxxxxxxx23456"));//秘钥,这个不能暴露 长度至少是16位,否则会报错

            var token = new JwtSecurityToken(
                //issuer: "http://localhost:5000",
                //audience: "http://localhost:5001",
                claims: claims,
                notBefore: DateTime.Now,//自动给Claim里面带了个时间戳参数nbf
                expires: DateTime.Now.AddMinutes(10),//自动给Claim里面带了个过期戳参数exp
                signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
            );

            var jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
            return jwtToken;
        }

issuer代表颁发Token的Web应用程序,audience是Token的受理者,如果是依赖第三方来创建Token,这两个参数肯定必须要指定,因为第三方本就不受信任,如此设置这两个参数后,我们可验证这两个参数。要是我们完全不关心这两个参数,可直接使用JwtSecurityToken的构造函数来创建Token,如下:

 var claims = new Claim[]
            {
                new Claim(ClaimTypes.Name, "Jeffcky"),
                new Claim(JwtRegisteredClaimNames.Email, "[email protected]"),
                new Claim(JwtRegisteredClaimNames.Sub, "D21D099B-B49B-4604-A247-71B0518A0B1C"),
                new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMilliseconds(1)).ToUnixTimeSeconds()}"),
                new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}")
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234567890123456"));

            var jwtToken = new JwtSecurityToken(new JwtHeader(new SigningCredentials(key, SecurityAlgorithms.HmacSha256)), new JwtPayload(claims));

然后是验证,需要在Startup里的ConfigureServices方法里加上使用jwt组件

在.net Core 3.0中使用jwt验证_第3张图片

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234567890123456")),

                    ValidateIssuer = false,
                    //ValidIssuer = "http://localhost:5000",

                    ValidateAudience = false,
                    //ValidAudience = "http://localhost:5001",

                    ValidateLifetime = true,

                    ClockSkew = TimeSpan.FromMinutes(5)
                };
                options.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("act", "expired");
                        }
                        return Task.CompletedTask;
                    }
                };
            });

 最后别忘记添加认证中间件在Configure方法中,认证中间件必须放在使用MVC中间件之前,如下:

复制代码

            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

复制代码然后是前端页面上


   

Welcome


   

Learn about building Web apps with ASP.NET Core.


    @*测试*@
   

   


验证token的方法是直接取,看是不是能取到,就拿我这个项目里面验证的方法CreateZipFile的时候

在.net Core 3.0中使用jwt验证_第4张图片

 

 //var Claims = User.Claims.Count(); //正常是可以获取到所有的Claims的,我试验如果吧token的串修改的话这个地方就取不到了,但还是会进来这个方法,所以要判断下是不是null

var sub = User.FindFirst(d => d.Type == JwtRegisteredClaimNames.Sub)?.Value;
            if (string.IsNullOrEmpty(sub))
            {
                return Json(new { code="0",id="",strErr="Token验证失败"});
            }
            var result = _Ziphelper.CreateFileAndZip(id);

            return Json(new { code = result.Code, Id = result.Id, strErr = result.strErr });

 

暂时只有这么多了,这只是用了最简单的... 

主逻辑是把key给使用api的那边了,毕竟登录的模块没在我这边,然后他那边生成token之后,发过来这边验证,返回验证信息,如果通过的话会生成zip文件,返回值判断正常就可以调用第二个参数把生成的对应文件下载下来

现在关于jwt的只有生成和验证,后面如果继续深入的话可以让jwt实现刷新,这个我继续跟踪那个博文看着比较复杂,还没有实现。

你可能感兴趣的:(jwt,jwt,.net,Core,C#)