JWT快速入门

jwt的比喻:

jwt就相当于钱,你可以拿钱去任何店铺,店铺做校验,1、是否是人民币而不是津巴布韦币(我认不认可),2、是否是“真钞”(防伪技术校验)。别人认同,你就能进入店铺并做这些钱能力之内的事情。

HTTP 是一个无状态的协议,在 Web 应用中,用户的认证和鉴权是非常重要的一环,实践中有多种可用方案,并且各有千秋。

基于session认证(类似先登记,后使用的粮票)

Session 是一种记录服务器和客户端会话状态的机制,在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,需要在数据库或者 Redis 中保存用户信息和token信息,所以它是有状态的。持久层万一挂了,就会单点失败。

基于token的认证(钱)

用户身份信息有服务生成,交由客户端管理token,所有数据都保存在客户端,每次请求将token发回服务器,服务端不需要保留用户的认证信息或者会话信息,这就为应用的扩展提供了便利。

在后端并不需要存储数据,直接通过私有密钥验证就可以了。客户端携带jwt请求时服务器在执行一遍签名步骤。如果签名的值一样就表示这个jwt是可靠的。此时我们在客户端和服务器之间就建立一种可信任的token机制。

Json Web Token(JWT)

JSON Web Token (JWT) is a compact, URL-safe means of representing
   claims(表示声明) to be transferred between two parties.  The claims in a JWT
   are encoded as a JSON object that is used as the payload of a JSON
   Web Signature (JWS) structure or as the plaintext of a JSON Web
   Encryption (JWE) structure, enabling the claims to be digitally
   signed or integrity protected with a Message Authentication Code
   (MAC) and/or encrypted.
 

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在两个组织之间传递安全可靠的信息。jwt其实相当于接口。有jws,jwe等不同的实现。

 

JWS(JSON Web Signature)、JWE(JSON Web Encryption)是JWT的一种实现。

jws(JSON Web Signed). 他本身的数据并没有进行加密。

jwe(JSON Web Encryption)对jwt进行加密.保证数据的安全。

JSON Web Encryption(JWE)

http://self-issued.info/docs/draft-ietf-jose-json-web-encryption.html

使用基于JSON的数据结构表示加密的内容。JWE加密传输数据,保证安全性与数据完整性。JWE由五部分组成:

 

  • The protected header,类似于JWS的头部;
  • The encrypted key,用于加密密文和其他加密数据的对称密钥;
  • The initialization vector,初始IV值,有些加密方式需要额外的或者随机的数据;
  • The encrypted data (cipher text),密文数据;
  • The authentication tag,由算法产生的附加数据,来防止密文被篡改。

一般来说,JWE需要对密钥进行加密,这就意味着同一个JWT中至少有两种加密算法在起作用。

JWE的计算过程相对繁琐,不够轻量级,因此适合与数据传输而非token认证,但该协议也足够安全可靠,用简短字符串描述了传输内容,兼顾数据的安全性与完整性。

JSON Web Signature(JWS)

JSON Web Signature是一个有着简单的统一表达形式的字符串,以签名形式保证数据完整性。

header

这个独立的对象就是一个JSON对象,叫JWT Header,Payload的内容在接收者端是通过签名(Signature)来校验的。不过存在多种类型的签名,因此,接收者需要知道使用的是哪种类型的签名。

jwt的头部承载两部分信息:

  • 声明类型,这里是jwt
  • 声明加密的算法

playload(有效载荷)

  • 标准中注册的声明 这些是一组预定义的claims,非强制性的,但是推荐使用, iss(发行人), exp(到期时间), sub(主题), aud(观众)等;
  • 自定义的claims,用于在同意使用这些claims的各方之间共享信息

这里可以查看JWT注册表

标准中注册的声明 (建议但不强制使用) :

  • iss: jwt签发者
  • sub: jwt所面向的用户
  • aud: 接收jwt的一方
  • exp: jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该jwt都是不可用的.
  • iat: jwt的签发时间
  • jti (JWT ID):编号

signature

保证了数据在传输过程中不被修改,验证数据的完整性。

将哈希结果附加到消息上,是为了让接收者可以验证。JWT的第三部分是由Header、Payload通过数字签名生成,并使用Base64Url进行编码。

HMAC:Hash-Based Message Authentication Code 是数字签名的一种形式

Header和Payload一起哈希 -》对哈希结果加密 -》Base64

提供数据的相关函数使用的签名算法通常是RS256(RSA非对称加密和私钥签名)和HS256(HMAC SHA256对称加密)算法。HS256要求JWT的生产者和消费者都预先拥有相同的密码,可能会有分发秘钥、数据签发不可溯源。

  • 为什么使用RS256?

1、使用RS256时,私钥只有认证服务器持有,这就安全得多- 加签密钥丢失的风险降低了。然而选择RS256更重要的理由是-简化密钥分发。

2、创建token和校验token的能力分开,只有认证服务器具备创建的能力,而应用服务器,具备校验的能力。和认证能力。

JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。

我们希望在网络上传输字符串时没有这些问题,那就需要选择这些字符的一个子集,对于这个子集,几乎所有的编码方式都是一样的处理方式,这就是Base64编码方式产生的原因。

使用jwt认证

 

Refresh Token

refresh token同access token 一起生成,表示更新令牌,过期所需时间比access toen 要 长,可以用来获取下一次的access token。

  • Access Token使用频繁,且与用户数据直接关联,安全性方面比较敏感,因此有效期设置得较短,即使Access Token泄漏也将很快失效。token即是获取受保护资源的凭证,当然必须有过期时间。否则一次登录便可永久使用,认证功能就失去了其意义。
  • Refresh Token仅用于获取新的Access Token,使用频率较低,不与用户数据直接关联,过期时间允许设置得长一些这样就解决了用户反复登录的问题。Refresh Token在用户和服务器通信过程中,不断变换Access Token,只能在一段时间内有效,增加了安全性。

常见问题:

1、作为登录态,如何实现登录态的管理功能,如统一踢出、禁用用户

2、如何获取敏感数据

3、如何续签

优缺点

JWT优点

  • JWT真正的好处是让认证服务器和校验JWT token的应用服务器可以完全分开,它使得将认证逻辑委托给第三方服务成为可能。服务器只需要最简单的认证逻辑-校验JWT。无状态的token不依赖于服务器保存会话信息,更利于水平扩展。
  • 服务器端无需保存token,服务端不再需要存储 Session,以加解密的方式代替存储,减少存储环节。
  • 设置在HTTP 请求的头信息Authorization字段里面。也能在禁用 Cookie 的浏览器环境中正常运行,相比于传统的session认证方式,jwt对移动端的支持更友好。
  • JWT的载荷中可以存储一些常用信息,用于交换信息,有效地使用JWT,可以降低服务器查询数据库的次数。
  • 基于标准化:API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft)

JWT缺点

  • 严重依赖于秘钥:JWT 的生成与解析过程都需要依赖于秘钥(Secret),且都以硬编码的方式存在于系统中(也有放在外部配置文件中的)。如果秘钥不小心泄露,系统的安全性将收到威胁。
  • 无法作废已颁布的令牌。所有的认证信息都在JWT中,由于在服务端没有状态,即使你知道了某个JWT被盗取了,你也没有办法将其作废。在JWT过期之前(你绝对应该设置过期时间),你无能为力。除非,我们在后端增加额外的处理逻辑。
  • 更多的空间占用、性能问题http请求的Header可能比Body还要大,需要考虑cookie的空间限制等因素,JWT保存在Local Storage中,然后使用Javascript取出后作为HTTP header发送给服务端的方案,如果放在Local Storage,则可能受到XSS攻击。在Local Storage中保存敏感信息并不安全
  • 用户信息安全。通过JWT 的组成结构可以看出,Payload 存储的一些用户信息,它是通过Base64加密的,可以直接解密,不能将秘密数据写入 JWT,如果使用需要对 JWT 进行二次加密。
  • 一次性、无状态是JWT的特点,但也导致了这个问题,JWT是一次性的。想修改里面的内容,就必须签发一个新的JWT。
  • 而且 token 模式也并非比传统 Session 更安全,他们都没有解决 CSRF 和 XSS 的问题。
  • 相比较session后端管理方式,过期时间续签繁琐

JWT适用场景

充分发挥jwt无状态以及分布式验证的优势、携带信息且有签名不可伪造。

  • 做那些短期的、一次性的安全认证验证需求,可以把有效时间设置的短一些,过期了就需要重新去请求,避免过期刷新。
  • 授权:这是最常见的使用场景,解决单点登录问题。可以轻松的在不同域名的系统中传递,服务端不用记录用户状态信息(无状态),所以使用比较广泛;
  • 信息交换:JWT是在跨服务之间安全传输信息的好方法。JWT最适合的应用场景就是“开票”,或者“签字”。因为JWT携带信息、可以签名,例如,使用公钥/私钥对儿 - 可以确定请求方是合法的。此外,由于使用标头和有效负载计算签名,还可以验证内容是否未被篡改。
  • 用于后续的审计、追溯等用途。服务B你好, 服务A告诉我,我可以操作<JWT内容>, 这是我的凭证(即JWT)

不要试图用jwt去代替session

  • 我们使用JWT的初衷就在于,我们可以不用通过读取状态来得知请求者的一些信息,因为JWT中自带了一些不敏感的信息。存储层不应该保存会话数据。
  • JWT撤销令牌,应该杜绝出现这种情况,使用JWT的场景如果需要撤销的功能,那么就不适合用JWT来做。需要后端服务器维护状态,不通跨域、跨服务之前相互调用。如果每一个请求到来的时候都要去读取状态并检测这个JWT是否有效,那么就和使用JWT的初衷相违背。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值