什么是无状态呢?就是说这一次请求和上一次请求是没有任何关系的,互不认识的,没有关联的。
看过电影《夏洛特烦恼》的小伙伴肯定记得夏洛和大爷的一段对话:
夏洛:大爷,楼上322住的是马冬梅家吗? 大爷:马冬什么? 夏洛:马冬梅。 大爷:什么冬梅啊? 夏洛:马冬梅啊。 大爷:马什么梅啊? 夏洛:……行,大爷,您先凉快吧。
「打岔」大爷记不住马冬梅,就如同 HTTP 协议记不住上一次请求。说得通俗一点:HTTP 的记忆力不太好,需要借助『助听器』。
记忆力不好的优点就是一个字「快」;缺点也很明显,需要借靠 cookie
、session
、token
等机制将客户端多次请求关联起来。
想象一下如果没有 cookie
、session
、token
这样的机制,我们在网站上每次点击都需要重新输入密码认证,这样槽糕的体验你还愿意继续用吗?
在讲解cookie
、session
、token
前我们先简单讲解两个概念:认证
、授权
。
认证(Authentication)简单来讲就是验证当前者的身份,证明你是你自己
。
最常见的认证方式是通过用户名
和密码
,除此之外还有:
为了确认用户的身份,防止请求伪造,在安全要求高的场合,经常会使用组合认证(也叫多因素认证),也就是同时使用多个认证方式对用户的身份进行校验。
授权(Authorization)简单来讲就是授予第三方访问用户资源的权限
。
在互联网应用开发中,主要通过下面几种方式实现授权:
cookie
最开始被设计出来是为了弥补HTTP在状态管理上的不足。cookie 存储在客户端
:cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。cookie 是不可跨域的
:每个 cookie 都会绑定单一的域名(包括子域),无法在别的域名下获取使用。服务器向客户端发送 Cookie 是通过 HTTP 响应报文实现的,在 Set-Cookie 中设置需要向客户端发送的cookie,cookie格式如下:
Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
(1)浏览器向服务器发送请求;
(2)服务器响应请求,向浏览器设置 cookie;
(3)浏览器将 cookie 存在本地,下一次请求带上该 cookie;
(4)服务器响应请求。
(1)name=value
键值对,设置 Cookie 的名称及相对应的值。
(2)domain
指定 cookie 所属域名,默认是当前域名。如果 cookie 的 domain 设置为 taobao.com,那么 item.taobao.com, order.taobao.com 都是可以共享 cookie 的, 但是访问 tmall.com 就不能共享 cookie 了,这就涉及跨域访问的问题,跨域问题如何解决,这里不展开,有兴趣可以自行搜索。
(3)path
指定 cookie 在哪个路径(路由)下生效,默认是 '/'。如果设置为 /abc,则只有 /abc 下的路由可以访问到该 cookie,如:/abc/read。
(4)expires
指定 cookie 的过期时间(GMT时间格式),到达该时间点后该 cookie 就会自动失效。
(5)max-age
HTTP 1.1中定义的,优先级高于 expires 字段。
max-age 表示 cookie 有效期,单位秒。如果为正数,则该 cookie 在 max-age 秒后失效;如果为负数,该 cookie 为临时 cookie ,关闭浏览器即失效,浏览器也不会以任何形式保存该 cookie ;如果为 0,表示删除该 cookie 。默认为 -1。
(6)HttpOnly
如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本读写该 cookie 的信息。
(7)secure
该 cookie 是否仅被使用安全协议传输,默认为false。当 secure 值为 true 时,cookie 在 HTTP 中是无效的。
session 翻译过来就是『会话』。用户打开一个浏览器, 点击多个超链接, 访问服务器多个web资源, 然后关闭浏览器, 整个过程称之为一个会话。
(1)session 的特点
(2)session 工作流程
(1)用户第一次请求,提交用户名密码等信息进行登录认证,服务器根据用户提交的信息进行鉴权,鉴权成功后创建 session 对象,并将 sessionId 塞入 cookie 中,浏览器收到响应信息将 cookie 存入本地;
(2)用户第二次请求,以查看订单信息为例,浏览器自动将当前域名下的 cookie 信息发送给服务端,服务端解析 cookie,获取到 sessionId 后再查找对应的 session 对象,如果 session 对象存在说明用户已经登录,继续下一步操作。
从上面的流程可知,sessionId 是 cookie 和 session 中间的一道桥梁。
需要注意:如果客户端禁用了 cookie,还可以通过 url 重写等方法传递 sessionId。
(1)token 的组成
token 是验证用户身份的凭证,我们通常叫它:令牌
。
最简单的token组成: uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,以哈希算法压缩成一定长的十六进制字符串)
(2)token 特点
(3)token 工作流程
第一步:客户端使用用户名密码或者扫码等形式请求登录;
第二步:服务端收到请求后进行鉴权,鉴权成功后服务端会生成一个 token 并发送给客户端,客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里;
第三步:客户端下一次向服务端请求资源的时候需要带着存储的 token;
第四步:服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据。
需要注意:
(1)JWT 是标准 化的 token
从本质上讲 JWT 也是一种 token,只不过 JWT 是被大家广泛接受的标准。
JWT 即:Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准(RFC 7519)。
JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息。
(2)JWT 的组成
JWT 共有三部分组成:
在https://jwt.io/网站上可以解析一个已知的 JWT:
jwt的头部承载两部分信息:声明类型
,这里是jwt;声明加密的算法
,通常直接使用 HMAC SHA256;
载荷就是存放有效信息的地方。主要包含三个部分:标准中注册的声明
;公共的声明
;私有的声明
。
jwt 的第三部分是一个签名信息,这个签证信息由三部分组成:header (base64后的);payload (base64后的);secret。
(3)JWT 的特点
在分布式微服务技术日趋流行的今天,大型网站的设计都尽量避免使用 session 实现 HTTP 状态化。
session简单粗暴,在服务端维护会话信息,在客户端保存session id,服务端能够轻易地把会话控制在自己的手中,但服务集群化产生了session共享的负担;
jwt(token)只在客户端保存会话信息,服务端通过密钥校验会话,(相比session)拿时间换空间,卸下了服务端集群共享会话信息的负担,同时也加大了服务端控制会话的难度。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8