JWT认证看这一篇就够了

基于Token的认证

通过上一篇你大体已经了解session和cookie认证了,session认证需要服务端做大量的工作来保证session信息的一致性以及session的存储,所以现代的web应用在认证的解决方案上更倾向于客户端方向,cookie认证是基于客户端方式的,但是cookie缺点也很明显,到底有哪些缺点可以跳转上一次的文章。那有没有一种比较折中的方案呢?有的

把认证信息保存在客户端,关键点就是安全的验证,如果能解决认证信息的安全性问题,完全可以把认证信息保存在客户端,服务端完全无认证状态,这样的话服务端扩展起来要方便很多。关于信息的安全解决方案,现在普遍的做法就是签名机制,像微信公众接口的验证方式就基于签名机制。

签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。

当用户成功登陆系统并成功验证有效之后,服务器会利用某种机制产生一个token字符串,这个token中可以包含很多信息,例如来源IP,过期时间,用户信息等, 把这个字符串下发给客户端,客户端在之后的每次请求中都携带着这个token,携带方式其实很自由,无论是cookie方式还是其他方式都可以,但是必须和服务端协商一致才可以。当然这里我不推荐cookie。当服务端收到请求,取出token进行验证(可以验证来源ip,过期时间等信息),如果合法则允许进行操作。

基于token的验证方式也是现代互联网普通使用的认证方式,那它有什么优点吗?

  1. 支持跨域访问,Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输.
  2. 无状态:Token机制在服务端不需要存储session信息,因为Token自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.
  3. 解耦 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可.
  4. 适用性更广:只要是支持http协议的客户端,就可以使用token认证。
  5. 服务端只需要验证token的安全,不必再去获取登录用户信息,因为用户的登录信息已经在token信息中。
  6. 基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python,PHP)和多家公司的支持(如:Firebase,Google, Microsoft).

那基于token的认证方式有哪些缺点呢?

  1. 网络传输的数据量增大:由于token中存储了大量的用户和安全相关的信息,所以比单纯的cookie信息要大很多,传输过程中需要消耗更多流量,占用更多带宽,
  2. 和所有的客户端认证方式一样,如果想要在服务端控制token的注销有难度,而且也很难解决客户端的劫持问题。
  3. 由于token信息在服务端增加了一次验证数据完整性的操作,所以比session的认证方式增加了cpu的开销。

但是整体来看,基于token的认证方式还是比session和cookie方式要有很大优势。在所知的token认证中,jwt是一种优秀的解决方案

jwt

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

头部

header典型的由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)。

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

Payload 部分也是一个JSON对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。

iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

除了以上字段之外,你完全可以添加自己想要的任何字段,这里还是提醒一下,由于jwt的标准,信息是不加密的,所以一些敏感信息最好不要添加到json里面

{
    "Name":"菜菜",
    "Age":18
}
Signature

为了得到签名部分,你必须有编码过的header、编码过的payload、一个秘钥(这个秘钥只有服务端知道),签名算法是header中指定的那个,然对它们签名即可。

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

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。需要提醒一下:base64是一种编码方式,并非加密方式。

写在最后

基于token的认证方式,大体流程为:

  1. 客户端携带用户的登录凭证(一般为用户名密码)提交请求
  2. 服务端收到登录请求,验证凭证正确性,如果正确则按照协议规定生成token信息,经过签名并返回给客户端
  3. 客户端收到token信息,可以保存在cookie或者其他地方,以后每次请求的时候都携带上token信息
  4. 业务服务器收到请求,验证token的正确性,如果正确则进行下一步操作

image

这里再重复一次,无论是token认证,cookie认证,还是session认证,一旦别人拿到客户端的标识,还是可以伪造操作。所以采用任何一种认证方式的时候请考虑加入来源ip或者白名单,过期时间,另外有条件的情况下一定要使用https。

更多精彩文章

image

76 声望
13 粉丝
0 条评论
推荐阅读
搞定秒杀,只需要这几步!!
灵魂拷问秒杀这种大并发的写场景,直接分库分表开干?应对秒杀活动的流量高峰很难吗?不要拿淘宝级别的秒杀忽悠我秒杀活动特点我敢说凡是做过电商的同学,都会遇到运营展开的秒杀,限时购等“高并发”的活动。市面...

菜菜阅读 1k

基于Seata探寻分布式事务的实现方案
随着业务的快速发展、业务复杂度越来越高,几乎每个公司的系统都会从单体走向分布式,特别是转向微服务架构。随之而来就必然遇到分布式事务这个难题,这篇文章通过seata框架总结了分布式事务的几种解决方案

京东云开发者2阅读 389

封面图
vivo 超大规模消息中间件实践之路
作者:vivo 互联网存储技术团队-Luo Mingbo、中间件团队- Liu Runyun本文根据“2022 vivo开发者大会"现场演讲内容整理而成。

vivo互联网技术2阅读 257

软硬件结合,分布式数据库 ZNBase 存储架构优化实践
ZNBase 是开放原子开源基金会旗下的首个分布式数据库项目,由浪潮大数据团队开源并捐赠。本文将介绍 ZNBase 的存储架构,以及 ZNBase 技术团队在其 KV 存储引擎基础上所做的优化实践。

KaiwuDB阅读 1.1k

封面图
浅析数据库多表连接:开务数据库的分布式 join 计算
Join 是 SQL 中的常用操作。在实际的数据库应用中,我们经常需要从多个数据表中读取数据,这时我们就可以使用 SQL 语句中的连接(join),在两个或多个数据表中查询数据。

KaiwuDB阅读 1.1k

封面图
开务数据库delete流程解读
delete主要分为两个部分,一个部分为scan过程,拉取表中的数据,第二部分,根据过滤条件,调用b.Del()函数删除对应的数据。相关逻辑计划对象图为:

KaiwuDB阅读 941

封面图
深入解析分布式数据库的 SQL 引擎优化
开务数据库(原:云溪数据库)的 SQL 引擎包含连接、编译、缓存、分布式日志和分布式执行五大服务组件,实现了多集群多节点协同的高效计算,大大提升了用户的查询效率。

KaiwuDB阅读 892

封面图
76 声望
13 粉丝
宣传栏