1.定义
JWT ( Json web token)认证机制, 为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准, 该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景
2. token和session区别
1.session认证
1.1 定义
http协议本身是一种无状态的协议,为了知道哪个用户发出的请求,服务器必须存储一份用户登录的信息,这会登录信息又在响应时传递给浏览器,用cookie保存起来,以便下次请求时发送给浏览器
1.2 问题
- 通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大
- session认证存在那台服务内存中,就只能去这台服务器上拿到授权资源,因而限制了负载均衡器的能力
- 因为基于cookie进行用户识别,如果cookie被截获,容易受到csrf跨站请求伪造攻击
2.token认证
2.1定义
token认证不需要在服务端保留用户的认证信息,token认证流程如下
- 用户使用用户名密码来请求服务器
- 服务器进行验证用户的信息
- 服务器通过验证发送给用户一个token
- 客户端存储token,并在每次请求时附送上这个token值
- 服务端验证token值,并返回数据
注意
1.token必须在每次请求时传递给服务器,且保存在请求头中
2.服务端要支持
CORS(跨来源资源共享)
策略,一般服务器响应头需要设置为Access-Control-Allow-Origin: *`
2.2 jwt构成
jwt由header(头部),载荷(payload),签证(signature)
2.2.1 header
jwt的头部承载两部分信息:
-
声明类型,这里是jwt
-
声明加密的算法通常直接使用HMAC SHA256
{ 'typ': 'JWT', 'alg': 'HS256' }
-
然后将头部进行base64加密
2.2.2 payload
载荷就是存放有效信息的地方,由标准中注册的声明
,公共的声明
,私有的声明
三部分组成
标准中注册的声明
- iss: jwt签发者
- sub: jwt所面向的用户
- aud: 接收jwt的一方
- exp: jwt的过期时间,这个过期时间必须要大于签发时间
- nbf: 定义在什么时间之前,该jwt都是不可用的.
- iat: jwt的签发时间
- jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
公共的声明:
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密
私有的声明
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息
定义一个payload:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
然后将其进行base64加密,得到JWT的第二部分
2.2.3 signature
签证由header(base64编码后)和 payload(base64编码后人),secret三部分组成,header与payload用.组成字符串,然后通过header中声明的加密方式进行加盐secret组合加密,从而构成jwt第三部分
// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'secret');
//TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意
jwt签发生成是在服务端,secret用来进行签发和jwt的验证,所以secret就是服务端的私钥,不能泄露,一旦泄露,客户端就可以自我签发
3.如何应用token
般是在请求头里加入Authorization
,并加上Bearer
标注:
fetch('api/user/1', {
headers: {
'Authorization': 'Bearer ' + token
}
})
注意
403表示收到访问请求,但是禁止访问