实际项目中经常用到cookie,session,token,知道是授权、验证用户身份用的,最近看了一个公众号文章,趁热记录一下它们究竟怎么工作的。
凭证:访问应用时对用户进行身份认证和授权的东东。
cookie和session
http是无状态的协议,每个请求都是独立的,服务端无法确认当前访问者的身份,无法辨认是不是同一个人,这个时候需要维护一个状态,用来告知服务端发送来的请求是否来自同一浏览器,这个状态可以用cookie或者session来实现。
两者的联系和区别:
1. 存储位置不同:
cookie是存在客户端的,cookie是服务端发送到用户浏览器并保存在本地的的一丢丢数据,它会在浏览器下次请求时被携带发给服务端
session是基于cookie实现的,存放在服务器端,sessionId会被存储在客户端的cookie里。
2. 跨域:
cookie时不能跨域的,因为每个cookie都跟一个域名绑定。但是通过domain可以在一级域名和二级域名间共享使用。
3. 数据格式:
cookie的格式是name=value,name,value只能是字符串类型,如果是Unicode字符,需要为字符编码;如果是二进制数据,需要base64编码大小不超过4k
session可以存放任意数据类型,大小不限,不过由于session存放在服务器内存里,太多了会消耗服务器资源。
4. 安全:
session比cookie安全,可以从存储位置看出来
5. 有效期不同:
cookie可以设置长时间有效,session失效一般很快,客户端关闭或者session超时都会失效
6. 由于cookie在移动端上不咋支持,所以移动端不用cookie和session来作为凭证
session和cookie如何工作,由图可知,sessionId是链接cookie和session的桥梁
token
token有access token 和 refresh token 两种
1. access token
是访问资源接口(API)是需要的资源凭证
简单的token可以由uid, time, sign等编码而成
特点如下:
- 服务器无状态变化,可扩展性好
- 支持移动端设备
- 安全
- 支持跨程序调用
token和session的区别:
1.状态:
session是记录服务器和客户端会话状态的,使服务端有变化,token是访问资源接口是要的凭证,使服务器无状态,不存储会话信息
2. 安全
token比session安全性好,session必须依靠链路层保障通讯安全;token是每个请求都有签名,能防止监听和重放攻击。
不过两者可以同时使用
3. session只是简单的把user信息存放到session里,sessionId是不可预测的;token提供认证(针对用户)和授权(针对app),token是唯一的,不能转移给其他app或者其他用户。
如果数据要跟第三方共享,允许第三方调用接口访问,用token
token的工作过程
客户端用账号密码登录,服务端收到请求后验证账号密码,验证通过会签发一个token返回客户端。
客户端收到token后存储到cookie或者localStorage里,每次请求服务端时带着token,可以放到Header里,服务端收到请求后验证token,验证通过就向客户端发送数据
2. refresh token
专门用于刷新access token的token,如果不用refresh token 每次access token失效后,需要输入账号密码来重新生成。有了refresh token,可以根据它直接生成一个新的access token
refresh token和access token工作机制如下
服务端一般不用存放token数据,拿到token进行解析,用解析时间换session的存储空间,时间换空间
token完全由应用管理,可以避开同源策略
JWT(JSON Web Token)
为了网络应用环境间传递声明而执行的基于JSON 的开放标准 。。。。。
用来在身份提供者和服务提供者之间传递用户身份信息
工作机制:
1. 用户输入用户名密码登录后服务端认证成功返回客户端一个JWT,客户端存到本地缓存
2. 当用户访问一个受保护的资源或路由时,在请求头的Authorization中用bearer模式添加JWT。(post请求时可以放到body中,或者通过URL传递:http://api/123?token=***)
3. 服务端检查请求头的JWT,(里面包含了一些会话信息,减少查库操作,不实用cookie,不担心跨域,也不存服务器内存)如果是合法的,允许用户行为。