Asp.net Core3.1 Jwt认证 简单使用

1、JWT介绍

 网上一搜就有很多关于JWT的介绍

官网上的介绍 :  JSON Web Token Introduction - jwt.io

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

尽管JWT可以被加密以提供各方之间的保密性,但我们将重点关注签名令牌。签名令牌可以验证其中包含的声明的完整性,而加密令牌对其他方隐藏这些声明。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方是对其进行签名的一方。

以前使用的较多的是Cookie认证(Asp.net Core3.1 Cookie认证 简单使用_ShanShanYouWen的博客-CSDN博客) 相对于一些小项目,不需要分布式部署的,认证和web应用同在一个项目里部署。现如今移动端APP对应的服务端一般都是无状态的API,JWT是无状态的支持分布式的身份验证方式。

2、JWT主要组成部分

Header.Payload.Signature

Asp.net Core3.1 Jwt认证 简单使用_第1张图片

Header:

标头通常由两部分组成:令牌类型(JWT)和使用的签名算法(如HMAC SHA256或RSA)

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

Payload:

   令牌的第二部分是有效载荷,其中包含声明。声明是关于实体(通常是用户)和其他数据的声明。索赔有三种类型:registered, public, and private claims.。

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

Signature:

要创建签名部分,您必须获取编码的头、编码的有效载荷、秘密、头中指定的算法,并签名.

HMAC SHA256算法如下:

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

3、JWT认证流程

下图显示了如何获取JWT并将其用于访问API或资源:

Asp.net Core3.1 Jwt认证 简单使用_第2张图片

认证流程:

  1.  客户端通过认证服务器获取一个Token。
  2. 在访问应用服务器或资源服务器的API的时候,将获取到的Token放置在请求的Header中。
  3. 应用服务器或资源服务器验证该Token,通过后返回对应的结果。

4、NetCore3.1 使用JWT认证

创建新的Asp.Net Web 项目

Asp.net Core3.1 Jwt认证 简单使用_第3张图片

 加载JwtBearer包

Asp.net Core3.1 Jwt认证 简单使用_第4张图片

 环境是NetCore3.1  所以选择3.1.30 版本

4.1、在配置文件配置JWT需要用到的参数

 "JwtConfig": {
    "Issuer": "issuer",
    "Audience": "audience",
    "SigningKey": "ac0d32c63@z43d-8717-vcsd-32fsdferuwqqvj",
    //过期时间(分钟)
    "Expires": 120,
    //是否验证过期时间
    "ValidateLifetime": true
  },

4.2、在Startup类中读取配置参数

      services.Configure(Configuration.GetSection("JwtConfig"));
      var jwtConfig = Configuration.GetSection("JwtConfig").Get();

4.3、添加JWT认证服务

 services.AddAuthentication(o =>
            {
                o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(o =>
            {
               
                o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                {
                    ValidateIssuerSigningKey = true,//是否调用对签名securityToken的SecurityKey进行验证
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SigningKey)),
                    ValidIssuer = jwtConfig.Issuer,//将用于检查令牌的发行者是否与此发行者相同
                    ValidAudience = jwtConfig.Audience,//检查令牌的受众群体是否与此受众群体相同
                    ValidateLifetime=jwtConfig.ValidateLifetime,
                    ValidateIssuer = false,//是否验证发行者
                    ValidateAudience = false//在令牌验证期间验证受众
                };
            });

4.4、添加中间件使用:

         app.UseAuthentication();

注: 一定要放在     app.UseRouting  和  app.UseEndpoints 中间。

4.5、如果要使认证生效,需要在方法或控制器上加特性   [Authorize], 需要授权才会生效。

 先测试一下,在默认的方法Privacy 上对比一下未添加特性   [Authorize] 和添加特性之后的效果

未添加之前点击Privacy,显示

Asp.net Core3.1 Jwt认证 简单使用_第5张图片

添加特性后 

        [Authorize]
        public IActionResult Privacy()
        {
            return View();
        }

启动项目,点击Privacy,弹出错误提示 401  未授权,无权限访问方法。

Asp.net Core3.1 Jwt认证 简单使用_第6张图片

4.6、调用方法生成Token,实现JWT认证

        private string GenerateToken(JwtConfig jwtConfig, User user)
        {
            var claims = new Claim[] {
             new Claim (ClaimTypes.Name,user.username)
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SigningKey));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var securityToken = new JwtSecurityToken(
                jwtConfig.Issuer, 
                jwtConfig.Audience, 
                claims,
                expires: DateTime.Now.AddMinutes(jwtConfig.Expires),
                signingCredentials: credentials);

            return   new JwtSecurityTokenHandler().WriteToken(securityToken); 
        }

        需要调用到配置参数JwtConfig以及登录时用户名称

定义参数类JwtConfig

 public  class JwtConfig
    {
        /// 
        /// 谁颁发的
        /// 
        public string Issuer { get; set; }

        /// 
        /// 颁发给谁
        /// 
        public string Audience { get; set; }

        /// 
        /// 令牌密码
        /// a secret that needs to be at least 16 characters long
        /// 
        public string SigningKey { get; set; }

        /// 
        /// 过期时间(分钟)
        /// 
        public int Expires { get; set; }

        /// 
        /// 是否校验过期时间
        /// 
        public bool ValidateLifetime { get; set; }
    }

        用户类User:

 public class User
    {
        public int ID { get; set; }
        public string username { get; set; }

        public string pwd { get; set; }

    }

简单获取用户信息的方法:

 public class UserBLL
    {
       
        public User GetUser(string username, string pwd)
        {
            return new User() { ID=1, username = username, pwd = pwd };
        }
    }

在控制器构造函数增加获取配置参数JwtConfig:

        private readonly ILogger _logger;
        private readonly JwtConfig _jwtoptions;

        public HomeController(ILogger logger, IOptions jwtoptions)
        {
            _logger = logger;
            _jwtoptions = jwtoptions.Value;
        }

登录方法:

        [HttpPost]
        public IActionResult Login(string username, string pwd)
        {
            var user = new UserBLL().GetUser(username, pwd);
            if (user != null)
            {
                string token = GenerateToken(_jwtoptions, user);
                return Ok(new { code = 0, msg = "success", Token = token }) ;
            }
            return NoContent();
        }

        

前端页面:


        
        
        

前端ajax调用登录:

       var token=""; 
        function submit()
        {
     
            $.ajax({
                url: "/Home/Login",
                type: "post",
                dataType: "json",
                data: {'username':$("#username").val(),"pwd":$("#pwd").val()},
                async: false,
              
                    success: function (d) {
                    var obj = JSON.stringify(d); 
                    console.log(obj); 
                    token = d.token; 
                     
                },
                error: function (d) {
                    alert(JSON.stringify(d))
                }
            });
        }

 要把登录后返回的token 保存

然后在页面添加一个a 标签用于访问授权的方法

    My Info
       function myinfo()
        { 
            $.ajax({
                url: "/Home/Info",
                type: "get",
                dataType: "json",
                async: false,
                headers: { "Authorization": "Bearer " + token },
                success: function (d) {
                    alert(d);
                    console.log(JSON.stringify(d)); 
                    $("#myinfo").html(d.data);
                },
                error: function (d) {
                    //alert(JSON.stringify(d))
                }
            });
        }
        [Authorize]
        public IActionResult Info()
        {
            return Ok(new { code = 0, msg = "success", data = "你有权限访问我的信息" });
        }

这样我们在前端不仅获取到token,还在调用方法的时候用上了token

headers: { "Authorization": "Bearer " + token }

运行项目

Asp.net Core3.1 Jwt认证 简单使用_第7张图片

输入账号密码登录成功后,点击My Info

Asp.net Core3.1 Jwt认证 简单使用_第8张图片

提示已有权限,点击Privacy,依旧无权限提示,因为我们没有在Header上加上Token

Asp.net Core3.1 Jwt认证 简单使用_第9张图片

我们用到第三方工具Postman调用接口,把token加上试试: 

未添加token,提示401 无权限

Asp.net Core3.1 Jwt认证 简单使用_第10张图片

添加token,访问

Asp.net Core3.1 Jwt认证 简单使用_第11张图片

 简单的调用实现JWT已完成,后续要封装的可以在此基础上完善。

网上参考看了许多文章,有很多封装很好,此文章只是简单的使用,初体验。

参考文章:JSON Web Token Introduction - jwt.io

『JWT』,你必须了解的认证登录方案 - 风的姿态 - 博客园

ASP.Net Core 3.1 中使用JWT认证 - Liuww06 - 博客园

demo:https://download.csdn.net/download/youwen1988/87349982

你可能感兴趣的:(JWT认证,Asp.net,Core3.1,认证,c#,.netcore)