Token 原理解读

前言

每种事物的产生,都有它的历史原因

上一篇文章我们了解了一下 cookie 与 session 的产生、作用与原理。尽管二者在历史中已经服役过很长一段时间,但不论什么技术,都会有后来的优秀者取而代之。

前面说到,cookie 因为是保存在客户端,所以有安全隐患,因而诞生了 session,session 保存在服务器端,相对安全很多。但 session 每次都要为用户开辟一个空间用于其身份校验,且每次浏览器的请求过来服务器都要进行校验请求,十分耗费服务器的空间与性能。

于是,另一种身份校验工具诞生了,这就是 token。

一、什么是 token

token,英语意为“令牌”

token

本质上还是用户身份验证的工具。但与 cookie、session 明文似的形式不同,token 是经过一系列加密手段加密过的,最后表现为一串“无意义”的字符串。但里面包含了许多信息,可能包括用户登录的终端的地址、用户身份 ID、时间戳以及一个签名。所谓签名就是信息发送者给这段信息进行签名,让信息接收方知道请求 token 是属于谁。可以理解为在你的身份证上签名字,证件加笔迹双重认证。

CSRF 攻击与同源策略

CSRF攻击,意为“跨站点请求伪造”

CSRF 攻击过程

  1. 用户 C 打开浏览器,访问受信任网站 A,输入用户名和密码请求登录网站 A;

  2. 在用户信息通过验证后,网站 A 产生 Cookie 信息并返回给浏览器,此时用户登录网站 A 成功,可以正常发送请求到网站 A;

  3. 用户未退出网站 A 之前,在同一浏览器中,打开一个 TAB 页访问网站 B;

  4. 网站 B 接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点 A;

  5. 浏览器在接收到这些攻击性代码后,根据网站 B 的请求,在用户不知情的情况下携带 Cookie 信息,向网站 A 发出请求。网站 A 并不知道该请求其实是由 B 发起的,所以会根据用户 C 的 Cookie 信息以 C 的权限处理该请求,导致来自网站 B 的恶意代码被执行。

同源策略

为了避免上述 CSRF 攻击,浏览器对网页资源的访问提出了限制,URL 请求必须是与页面一样来自同一协议域名端口才给予访问权限。这样三者相同的站点被认为是有相同的“源”,是一个独立的“域”。即使 “localhost” 与 “ip” 都指向了本机,但也会被认为是非同源。浏览器在某个“域”下不会执行其他“域”的脚本。因而这也产生了前端领域里一个重要的话题:跨域。

session 的产生来自于用户登录后服务器生成的一个 session 对象,保存在服务器端,这个 session 只适用于该“域”。但实际情况是,一个网站的请求大多数情况下都会跨域,每台服务器的端口不同,甚至是域名就不同,每当跨域时就会形成新的会话,生成新的 session,这是非常影响用户体验的,所以也会有许多保存、共享或中央存储 session 的方案。

但上述两种限制在 token 这里就不再是问题。

token 的优势

  1. 如果有恶意站点利用本地 cookie 对其他站点进行可以攻击,token 可以作为一种身份验证机制限制这种“攻击式的请求”,可以有效避免 CSRF 攻击
  2. token 因为保存在浏览器端,可以避开同源策略
  3. token 是随机生成的,具有不可预测性和防暴力拆解性
  4. 移动端没有 cookie 与 session,token 可以有效兼容移动端
  5. token 也可以设置过期时间,让其具有时效性,把控用户登录的状态与安全

二、token 验证流程

与 cookie 类似。

首先,用户输入账号密码,发起登录请求,服务器校验账号密码合法性,成功则返回 token 给客户端。

客户端收到响应后拿到 token,将其通过 localStorage 等本地存储方式进行保存。

当浏览器再次请求时,需要在请求头中添加 token,这样服务器在接收到请求后便可以识别该请求的身份是否合法,合法则返回响应数据。

在实际应用中,配合 axios 的请求拦截器使用起来会很方便:

request.interceptors.request.use(config => {
  const token = window.localStorage.getItem('token')
  if (token) {
    config.headers.Authorization = token
  }
  return config
})

这样,就不用每次请求都手动添加 token,axios 会自动帮助我们完成添加,十分方便。

后记

其实前端程序员对 token 的涉及没有多深,只需要在需要授权的请求中携带 token 即可。token 的生成、加密等都是后端去处理。所以,这里也就不在赘述 token 的加密原理,以笔者的能力也很难去讲述清楚。

token 运用也不是上文中描述的那么简单,涉及到一些过期处理、refresh 等操作。这些日后有机会再详谈。

你可能感兴趣的:(Token 原理解读)