开篇语
本文内容参考多位大佬的文章编写而成。
介绍
jwt是一个基于json的、用于在网络上声明某种主张的令牌,jwt通常是用三部分组成:头信息,消息体,签名。他是一种双方之间传递安全信息的表述性声明规范。主要用于集群分布式中。
作用:可以做权限验证的使用,是一种标准化的数据传输规范,但是目的不是为了数据加密和保护。
使用场景
- 授权:用于授权而并非是身份验证。通过身份验证,我们验证用户的用户名和密码是否有效,并将用户登录到系统中,通过授权,我们可以验证发送到服务器的请求是否属于通过身份验证登录的用户,从而可以授予该用户访问系统的权限,继而批准该用户使用获取的token访问路由、服务和资源。
- 信息交换:json web token是在双方之间安全地传输信息的一种好方法。因为jwt可以被签名,所以使您能够确保发送方是他们声称的那一方,由于签名使用header和payload计算的,因此还使您能验证发送的内容没有被篡改。
对比token+redis
JWT就是Json Web Token,就是Token的典型方式。JWT和Token+Redis的区别,其实都是Token,只是JWT的可靠性保障是来源于加密算法(对称加密和非对称两种),而Token+Redis的方案是依靠的后台数据存储。这两个本质也就带来了使用上的区别:
1 JWT是去中心化的,不需要任何后台数据的共享,第三方认证、跨数据中心认证、微服务等,都适合采用JWT的方式,当然,因为是去中心化的,不是实时验证,所以本质上来说token的主动过期是做不到的(要做到就会违背初衷)
2 Token+Redis是中心化的,要能识别token必须能访问该Redis,除非是有特别需求,要求每次token都实时检测,否则的话还是选择JWT,毕竟是成熟通用的技术,沟通维护成本也低,对开发者也友好一些。
这点我忘记是摘录哪个大佬的文章了,所以没有给出引用地址很抱歉。
流程
用户通过登录去向服务系统发起请求,然后生成带一定用户信息的数据作为令牌(jwt)返回给用户,用户拿到返回过来的信息在请求接口的时候放入头部,服务系统会从头部获取到令牌后验证签名的有效性,对客户端做出相应的响应。
- Authorization: Bearer <token>
如果想在接口中获取jwt令牌,可以使用
- var tokenHeader = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
现在感觉作用就是可以通过jwt实现权限,在系统中定义好有哪些权限,然后在方法头部去设置哪些角色可以去访问这个东西。如果存放token,我的想法是把用户的信息放到jwt内部,然后前端通过登录去获取这东西,然后我返回这个东西到前台,每次调用接口时候把这个东西传出过来,然后我通过将这个解密获取到我登录时候存进去的信息。然后进行我自己的操作。
注意:
生成jwt时候的key必须在16位以上,否则会因为长度不够抛出异常
jwt本身是不加密的,里面包含的信息任何人都可以读取到。
jwt的签名部分是对前两部分的签名,防止数据被篡改,
Bearer认证
Bearer认证(也叫做令牌认证)是一种HTTP认证方案,其中包含的安全令牌的叫做Bearer Token。因此Bearer认证的核心是Token。那如何确保Token的安全是重中之重。一种方式是使用Https,另一种方式就是对Token进行加密签名。而JWT就是一种比较流行的Token编码方式。
验证
- //全局增加配置
- services.AddControllers((options) =>
- {
- options.Filters.Add(new AuthorizeFilter());//添加全局的Authorize
- });
- //控制器或者方法增加配置
- [Authorize]
原理
- 获取token
- 第一步:对token进行切割
- 第二步:对第二段解码,获取payload,检测token是否超时
- 第三步:把前两段拼接再次执行HS256加密,把加密后的密文和第三段比较。如果相等,认证通过
参考文档
晓晨:https://www.cnblogs.com/stulzq/p/7417548.html
老张的哲学:https://www.cnblogs.com/laozhang-is-phi/category/1413402.html