Skip to main content

Command Palette

Search for a command to run...

Token Intro

Published
1 min read
T

A simple developer.

Token 概述

Token 的作用/目的

背景(引言)

我们都知道一般接口但是通过 HTTP 协议来进行数据交换的,而 HTTP 协议的特点是,无状态,工作前通过三次握手建立连接,工作完成后立刻通过四次挥手断开连接,每次连接都是独立存在的(这里不谈keep-alive的http),没有任何状态将请求串联成一个整体,因此每次都需要重新验证是身份,即耗费了性能,也给黑客的攻击留下隐患。

继而由此,我们需要一种能够存储当前状态的技术,此时cookies粉墨登场。

Cookies 存储 Token

Cookie 就是来弥补 HTTP 无状态的问题的,Cookie可以作为一个状态保存的状态机,用来保存用户的相关登录状态,当第一次验证通过后,服务器可以通过set-cookie令客户端将自己的token保存起来,当下一次再发送请求的时候,直接带上token即可,而服务器收到到客户端发送的token`后,进行验证(比如解密出用户信息,或者将其当作一个钥匙,去服务端数据库中拿数据来校验),则直接信任该连接,不再需要进行额外验证操作。

LocalStorage 存储 Token

从目的出发本质上与cookie存储没有区别,都是存储身份认证信息

简单来说,就是一种验证信息,客户端通过登录验证后,服务器会返回给客户端一个加密的 token,然后当客户端再次向服务器发起连接时,带上token,服务器直接对token进行校验即可完成权限校验。

而将 token 存储在 localStorage 内,有以下区别:

  1. Cookie 作为 HTTP 规范,其出现历史久远,因此存在一些历史遗留问题,比如跨域限制等,并且 Cookie 作为 HTTP 规范中的内容,其存在默认存储以及默认发送的行为,存在一定的安全性问题(CSRF攻击)

CSRF攻击:由于用户登录校验信息在cookie中,则如果当前浏览器登陆了A网站后,在B网站(攻击网站)中存在一个请求指向了A,此时由于 cookie 是基于 【客户端 - 服务器】,所以此时二者都没变的情况下,cookie 将会被携带进去作为一次合法请求,如此实现了攻击。

A: 已登录,将认证令牌放在cookie: { session: xxx }

用户进入B网站: 
    进入后B网站立即执行一条请求 https://A.com/post/deleteAll 删除全部文章
    此时,由于A网站已登录,该请求会携带上上次登录设置的cookie,从而认为是一次合法请求。
    --> 结果:当前用户在A网站的所有文章都被删除了。
  1. localStorage 是浏览器提供的存储功能,能够以键值对的方式进行数据存储,且数据能持久化被存储,即使浏览器关闭后也不会清除。而 localStorage 不会像 cookie 一样自动被带到请求中,故此可以避免CSRF攻击的发生。

  2. 从上面对于 localStorage Token 和 Cookie token 的分析,我们知道了 Cookie 由于存储的内存空间只有 4kb,因此存储的主要是一个用户 id,其他的用户信息都存储在服务器的 Session 中,而 localStorage 的内存空间更大(5MB左右),用户信息可以存储到 Token 中,返回给用户自行存储,因此可以看出,采用 Cookie 的话,由于所有用户都需要在服务器的 Session 中存储相对应的用户信息,所以如果用户量非常大,这对于服务器来说,将是非常大的性能压力,而Token 将用户信息返回给客户端各自存储,也就完全避开这个问题了。

Tokenrefresh Token

原始的认证 Token

最原始的认证 Token,即当认证完毕后,服务端给该token设置有效期,在有效期内接口携带该token(不管是cookie/其他地方的参数),服务端都认为是合法有效的。

优点:

简单有效,无需太多复杂的token管理逻辑,对于快速开发,安全性要求不太高的项目来说很方便。

弊端:

设置一个固定的过期时间,如果时间过短,则会导致用户体验不好,可能用户登录后,正在填写表单时突然就过期退出了;如果时间过长,则会将安全性问题放大,一旦被非法获取后长时间未过期,在这段时间攻击者则可以利用该token持续进行攻击了。

refresh token

为了解决单纯 token 过期时长问题而解决

从上面我们能知道,token 过期时间设置的过长/过短都有各自的缺陷,过长时安全有问题,而过短时则用户体验不好。

从这点出发,提出了 refresh token 的方案。

  1. 服务端在下发 token 的同时,下发一个 refreshToken 该 refreshToken 可用于请求一个新的有效 token。

  2. 为 token 设置一个很短的有效期,并设置一套保活逻辑,如有效期为24h(包括refreshToken),保活时间为 1h,则当用户在 1h 内没有进行请求时(或部分请求,有些接口服务端可设置黑白名单),会将该 token 过期。

  3. 此时前端使用过期 token 发出请求,服务端返回特定错误后,前端向服务端发出 api/refreshToken 请求,将 refreshToken 传入,获取一组新的 token / refreshToken。

  4. 该 refreshToken 过程应该是用户无感知的,如此能够做到用户体验的提升,同时满足了系统安全性要求。

More from this blog

Git 无法正常访问问题解决 —— DNS无法解析git地址

在国内网络经常会无法访问github,一般呈现错误为: github.com 打不开 git 操作 clone/push/pull/fetch 超时等 这普遍由于国内DNS解析github相关域名的问题,国内DNS解析污染会导致,无法解析github相关域名,使得我们无法获悉正确ip而无法访问。 偏方一剂:修改Host,固定绑定 domain - ip 查询相关域名的解析 IPAddress github.com github.global.ssl.fastly.net asse...

Sep 22, 20221 min read

Vue SSR实战小练

思想 开发环境: 在webpack dev与pro的前端打包构建基础上, 添加webpack server compiler的服务,其为单独创建的node服务,用于渲染html代码并返回给客户端。(其他JS...则仍旧交由webpack dev server来构建) 所以在获取html后要再自行将dev客户端渲染的js加入到html中 在生产环境则不需如此: 由dev与server打包好的文件,将其组合 客户端则访问node服务来获取文件 基本用法 安装:npm install v...

Sep 5, 20229 min read

Jsonp 跨域解决方案解析

由来背景 As we all know,浏览器同源策略会将非同源请求(跨域)抛弃,而许多时候我们可能并未将前端资源与服务端服务放在一个服务器,此时就需要一个跨域的手段了。 基于此,针对同源策略,衍生了一种跨域的方法Jsonp。 Jsonp简单讲,即利用了script标签不受浏览器同源策略影响的特性,从而利用script想服务端跨域请求的方式。 原理解析 图下图所示 封装一个Jsonp函数,Promise化 // jsonp.ts type JsonpOptions<T extends Reco...

Sep 2, 20222 min read
Jsonp 跨域解决方案解析

唯在一心

15 posts

A simple developer.