浅谈 Cookie-Session 、Jwt 两种身份认证机制

HTTP 是无状态的协议

咱们都知道 HTTP 是无状态(stateless)的协议:HTTP 对于事务处理没有记忆能力,不对请求和响应之间的通讯状态进行保存。 使用 HTTP 协议,每当有新的请求发送时,就会有对应的新响应产生。协议自己并不保留以前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特地把 HTTP 协议设计成如此简单的。html

但是,随着 Web 的发展,早期这种无状态的特性却带来了不少不方便性,好比说用户登陆新浪微博,在登陆页输入用户名、密码以后进入首页,可是因为 HTTP 是无状态的,HTTP 并不知道上一次的 HTTP 请求是否经过了验证,更没法得知当前用户的具体信息。前端

最简单的解决方案就是在全部的请求里面都带上用户名和密码,这样虽然可行,可是大大加剧了服务器的负担(对于每一个 request 都须要到数据库验证),并且用户也要每进入一个页面输入一次密码,毫无用户体验可言。web

为此,引入了各类身份认证机制,这里说一下 Cookie-Session 和 Jwt 机制。算法

Cookie-Session 机制

什么是 Cookie?

Cookie 是由 HTTP 服务器设置的,保存在浏览器中的小型文本文件,其内容为一系列的键值对。在 Chrome 中,经过开发者工具 -> Application -> Cookies 可查看 数据库

保存在浏览器中的 Cookie
这里简单介绍一下一些字段意思:

Expires:Cookie 的过时时间,默认过时时间为用户关闭浏览器时。json

HttpOnly:指示浏览器不要在除了 HTTP(或者 HTTPS)请求以外暴露 Cookie。经过 JavaScript 脚本没法访问到 Cookie,能有效防止 XSS 攻击后端

Secure:设置 Cookie 的 Secure 属性为 true 时,意味着 Cookie 通讯只限于加密传输,指示浏览器仅仅在经过安全/加密链接才能使用 Cookie。也就是说 Cookie 只有在 HTTPS 协议下才能上传到服务器,而 HTTP 协议下是没法上传的。跨域

Cookie 传递过程

  1. 浏览器向某个 URL 发送请求
  2. 对应的服务器收到该 HTTP 请求,生成要发给浏览器的 HTTP 响应
  3. 在响应头中加入 Set-Cookie 字段,值为要设置的的Cookie
  4. 浏览器收到来自服务器的 HTTP 响应
  5. 浏览器在响应头中发现了 Set-Cookie 字段,就会将该字段的值保存在内存或者是硬盘中。
  6. 当下一次向该服务器发送 HTTP 请求时,会将服务器设置的 Cookie 附加在 HTTP 请求的字段 Cookie 中。
  7. 服务器收到这个 HTTP 请求以后,发现请求头中有 Cookie 字段,就知道了已经处理过这个用户的请求了。
  8. 过时的 Cookie 会被删除

Cookie 传递过程

什么是 Session?

相对于保存在浏览器中的 Cookie,Session 是存储在服务器端的,避免了在客户端中储存敏感数据。而且存取方式不一样,Cookie 只能保存 ASCII 字符串,例如须要存取 Unicode 字符或者二进制数据,须要先进行编码。而Session中可以存取任何类型的数据。Session 通常配合 Cookie 使用,也就是接下来要说到的 Cookie-Session 机制。浏览器

基于 Cookie-Session 身份验证机制的过程

  1. 用户输入登陆信息
  2. 服务端验证登陆信息是否正确,若是正确就在服务器端为这个用户建立一个 Session,并把 Session 存入数据库
  3. 服务器端会向客户端返回带有 sessionID 的 Cookie
  4. 客户端接收到服务器端发来的请求以后,看见响应头中的 Set-Cookie 字段,将 Cookie 保存起来
  5. 接下来的请求中都会带上这个 Cookie,服务器将 sessionID 和 数据库中的相匹配,若是有效则处理该请求
  6. 若是用户登出,Session 会在客户端和服务器端都被销毁

Session-Cookie 机制的缺陷

  1. 扩展性很差,当拥有多台服务器的状况下,如何共享 Session 会成为一个问题,也就是说,用户第一个访问的时候是服务器 A,而第二个请求被转发给了服务器 B,那服务器 B 没法得知其状态。(举例来讲,A 网站和 B 网站是同一家公司的关联服务。用户只要在其中一个网站登陆,再访问另外一个网站自动登陆)
  2. 安全性很差,攻击者能够利用本地 Cookie 进行欺骗和 CSRF 攻击。
  3. Session 保存在服务器端,若是短期内有大量用户,会影响服务器性能。
  4. 跨域问题,Cookie 属于同源策略限制的内容之一。

Jwt 机制

JWT(JSON Web Token) 是由 RFC7519 定义的,是一个在双方之间安全的传达一组信息的 JSON 对象。安全

JWT 组成

JWT 由三个部分组成:header、payload、signature 每一个部分中间使用 . 来分隔,其中,header 和 payload 使用 Base64URL 进行编码:

base64UrlEncode(header).base64UrlEncode(payload).signature
复制代码

header

header 部分是一个 JSON 对象,用来描述 JWT 的元数据:

{
  "typ": "JWT",   //  表示对象是一个 JWT
  "alg": "HS256"  //  表示使用哪一种 Hash 算法来建立签名,这里是 HMAC-SHA256
}
复制代码

payload

payload 部分也是一个 JSON 对象,实际须要传递的数据被存放在这里。咱们除了使用官方提供的七个字段以外,也可使用自定义的私有字段。

{
  "sub": "title",
  "name": "Yeoman"
}
复制代码

JWT 默认是不加密的,任何人均可以读到,因此不要把秘密信息放在这个部分。

signature

signature 是对前两个部分的签名,防止数据被篡改。

data = base64urlEncode( header ) + "." + base64urlEncode( payload );
signature = Hash( data, secret );
复制代码

使用 Base64URL 编码的 header 和 payload 中间用 . 隔开,再使用 header 中指定的 Hash 算法,加上密钥对这个字符串进行 Hash 获得 signature

工做流程

  1. 前端将本身的用户名和密码发送到后端的接口
  2. 后端核对用户名和密码以后,将用户的一些信息做为 payload,生成 JWT
  3. 后端将 JWT 做为登陆成功的返回结果返回给前端。前端能够将其结果保存在 localStorage/sessionStorage 中,登出时删除 JWT 便可。(最好不要保存在 Cookie 中,用了 Cookie 就不能设置 HTTPonly,而且存在跨域问题)
  4. 每一次请求都将 JWT 放在 HTTP 请求头中的 Authorization 位,这样相比放在 Cookie 中能够跨域。
Authorization: Bearer <token>
复制代码
  1. 服务器解码 JWT,若是 token 有效,那么处理这个请求
  2. 用户登出,在客户端删除 token 便可,与服务端无关

JWT 特色

  1. JWT 默认是不加密的
  2. JWT 的目的是用来验证来源可靠性,并非保护数据和防止未经受权的访问。(能够类比成一张电影票,只能验证电影票是不是真的,电影票也有一些基本信息,可是他人也可使用你的电影票,若是可能的话)一旦暴露,任何人均可以得到权限。为了减小盗用,JWT 的有效期应该设置得比较短,对于一些比较重要的权限,使用时应该再次对用户进行认证。
  3. 最大的缺点是 token 过时处理问题,因为服务器不保存 Session 状态,所以没法在使用过程当中废止或者更改权限。也就是说,一旦 JWT 签发了,在到期以前就会始终有效,除非服务器部署额外的逻辑。

复习

这里再次复习一下相关知识:

同源策略限制的内容

  1. Cookie、LocalStorage、SessionStorage、IndexedDB 等存储性内容
  2. DOM 节点
  3. Ajax 发送请求后,结果被浏览器拦截

Cookie 和 Session 的区别

  1. 存取方式不一样:Cookie 只能保存 ASCII 字符串,例如须要存取 Unicode 字符或者二进制数据,须要先进行编码。而Session中可以存取任何类型的数据
  2. 隐私策略不一样:Cookie 存储在浏览器中,Session 存储在服务器上。
  3. 服务器压力不一样:Session 是保管在服务器上的,每一个用户都会产生一个 Session 。假如并发访问的用户十分多,会产生大量的 Session ,耗费大量的内存。

援引

JSON Web Token 入门教程

浅谈session,cookie和jwt(Json Web Token)认证方式

cookie-session机制与JWT机制对比

五个步骤轻松弄懂 JSON Web Token(JWT)

相关文章
相关标签/搜索