1.jwt
jwt
一 概述
1 简介
JWT(Json Web Token)是最流行的跨域认证解决方案之一。JWT是一个基于 RFC 7519 的开放数据标准,它定义了一种宽松且紧凑的数据组合方式,使用 JSON 对象在各应用之间传输加密信息。该 JSON 对象可以通过数字签名进行鉴签和校验,一般地,JWT 可以采用 HMAC 算法,RSA 或者 ECDSA 的公钥/私钥对数据进行签名操作。
jwt和传统session认证的比较
传统session认证:
缺点:
通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大
如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。
CSRF(Cross-site request forgery): 跨站点请求伪造,因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。具体见安全部分笔记。
jwt认证:
优点:
跨语言支持/跨服务调用:可以构建一个认证中心来处理用户身份认证和发放签名的工作,其他应用服务在后续的用户请求中不需要(理论上)在询问认证中心,可使用自有的公钥对用户签名进行验证
可以在自身存储一些其他业务逻辑所必要的非敏感信息
可以减少对数据库的调用(必要的信息还是要从数据库拿)
便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。不过也要看跟什么比较
无状态:不需要在服务端保存会话信息, 所以它易于应用的扩展
特点
因为JWT默认是不加密的,任何人都可以读到。所以使用时需要注意几点:
不应该在jwt的
payload
部分存放敏感信息,因为该部分是客户端可解密的部分。保护好secret私钥,该私钥非常重要。
如果可以,请使用https协议
生成原始 Token 以后,可以用密钥再加密一次。
JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
缺点
无状态
JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,如果用户身份发生异常(信息泄露,或者被攻击),服务端很难向操作 Session 那样主动将异常用户进行隔离,除非服务器部署额外的逻辑.
无法主动推送消息
严重依赖于秘钥:JWT 的生成与解析过程都需要依赖于秘钥(Secret),且都以硬编码的方式存在于系统中(也有放在外部配置文件中的)。如果秘钥不小心泄露,系统的安全性将收到威胁。
冗余的数据开销:一个 JWT 签名的大小要远比一个 Session ID 长很多,如果你对有效载荷(payload)中的数据不做有效控制,其长度会成几何倍数增长,且在每一次请求时都需要负担额外的网络开销。
原理
JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。
以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名,服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。
JWT的数据结构
它是一个很长的字符串,中间用点(.)分隔成三个部分,内部是没有换行的。形如Header.Payload.Signature
,JWT 的三个部分依次如下:
Header
(头部):Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。Payload
(负载):Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据,一般叫做Claim。JWT 规定了7个官方字段,供选用。还可以在这个部分定义私有字段,如Signature
(签名):Signature 部分是对前两部分的签名,防止数据篡改。首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256)
生成JWT的公式
Base64URL
这个算法跟 Base64 算法基本类似,但有一些小的不同:JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。
JWT 的使用方式
使用流程大概是:
先访问登录接口,成功后服务器会返回JWT给客户端
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,并且加上 HttpOnly 的标记,意味着这个 cookie不能被 JS获取,这样可以防止 XSS 攻击;也可以储存在 localStorage。此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
3. 服务器拿到客户端传递过来的JWT,去查找客户信息,找到且没过期就认为它是已登录的。
JWT 可以设置过期时间,它的应用主要有
Access Token:添加到 HTTP 请求的 header 中,进行用户认证。加上过期时间可以让 token 被恶意截获后,黑客只有短暂的时间攻击。 Refresh Token:用来给客户端申请新的 Access Token 或者 Refresh Token。比 Access Token 有更长过期时间。
3 常识
jwt可以看做本身没有任何加密机制,它依赖于https的通道保密能力
4 文档地址等
jwt介绍:https://jwt.io/introduction/
二 安装配置
三 基础
四 高级
JWE
五 经验
1 针对令牌泄漏的系统完善
服务器也保存一份令牌:用户请求时对比令牌是否一致,不一致的时候就删除并强制用户重新认证。
敏感操作保护:涉及到诸如新增,修改,删除,上传,下载等敏感性操作时,强制用户认证。比如扫码或手机验证码
地域检查
监控请求频率:比如一秒内发起了5次请求
客户端环境检查:对于移动应用,可以将用户信息和设别信息进行绑定。
Last updated
Was this helpful?