Jwt token存储在cookie还是web storage

Posted by zjh on August 7, 2020

首先,是登录信息:

登录信息存在 cookie 中是一直以来的做法,而且实现的很好,不用考虑各种问题。
而 localStorage 是在这个 API 诞生之后,一些 JS 党带起来的另一种实现方式。
使用 localStorage,你需要在每次请求的时候,都手动带上这个信息,这大大增加了开发过程中带来的困难,非常麻烦,而且还要手 动维护过期时间。
而使用 cookie 的话,只需要在后端的 Auth 模块放个设置 header 的代码即可,其他完全不用考虑。为什么:
用户未登录的情况下,Auth 判断没有权限,设置个跳转到登录页(或者是其他逻辑,比如以访客身份浏览之类的)
用户登录时:将账号和密码 POST 到 Auth 模块后,Auth 设置一个 header,设置 Cookie 及过期时间
用户登录后,在 Cookie 的有效期内(设置了过期时间就是过期时间内,没设置就是浏览器关闭前),任何请求都会自动带上cookie,完全不用人工干预(fetch 请求除外,需要额外指定配置)
在用户自动带上 cookie 请求后,需要授权的请求一定会经过 Auth 模块,判断 cookie 是否有效(防止恶意无效的 cookie),若 cookie 无效,则设置 header 删除 cookie(可选步骤),并将用户重定向到登录页。若 cookie 有效,则设置 header,为cookie 续期(cookie 内容都可以完全不变)。

Auth 模块:

if (POST 方法请求登录) {
 if (账号密码不正确) {
 return 重定向到登录页面,并提示错误
 }
 设置 cookie,并指定过期时间为当前时间 +n 天
 return Auth 模块逻辑结束,进入其他模块逻辑
}
if (没有 cookie) {
 return 重定向到登录页面
}
if (cookie 无效) {
 // 可选步骤:设置 cookie 过期时间为 -1 (删除 cookie)
 return 重定向到登录页面
}
// 带了有效的 cookie

设置 cookie 过期时间为当前时间 +n 天(为 cookie 续期)
return Auth 模块逻辑结束,进入其他模块逻辑
注意:只有请求 Auth 模块才会给 cookie 续期,其他模块不续。所以权限认证的模块都统一到一起了。
前端 js 什么都不用管,后端其他模块也什么都不用管。

然后是楼主的问题:

/ 登录/设置密码:这是两个模块,不能搞混概念!然后有一个权限管理模块(Auth)来管理。
首先,必须要用户登录才能操作,这里不管你把登录信息存储到哪里。

登录成功后,有两种选择:

1. 跳到首页,然后判断没有设置密码,跳到设置密码页

2. 直接判断是否设置密码,跳转到密码页。如果没有设置密码,强行进入主页,又需要判断然后跳到设置密码页。

可以看出来,首页中判断是否设置了密码是必须的,而登录页不是。
那么,将判断代码放在首页,登录成功后进入首页,首页判断没有设置密码再跳到设置页,设置成功后,再跳转到首页。这个逻辑没
有问题,也不会出现重复登录的问题。
首页:

if (未登录) {
 return 跳转到登录页;
}
if (未设置密码) {
 return 跳转到设置密码页;
}
// 已成功登录并设置密码,显示页面。
---------------------------------
登录页:
if (已登录) { // 防止用户将登录页加入书签,或者由于某些原因在已登录的情况下进入登录页
 return 跳转到首页;
}
// 未登录,显示登录页

登录成功后直接跳回首页。 ——————————— 设置密码页: if (已设置密码) { 显示修改密码页 } else { 显示设置密码页 } 设置成功后直接跳回首页。 我不知道楼主设置密码后为什么会跳转到登录页面?既然已经登录了,在设置密码后应该直接跳回首页啊?这应该是其他方面的逻辑 问题,而不是登录信息存储方式的问题吧? 最后补充一点:关于什么时候用 cookie,什么时候用 **Storage 注:上面的 **Storage 包括了 localStorage 和 sessionStorage。 Cookie: Cookie 存储的数据量比较小,所以一般不会存大量数据。当你存储的内容在每次请求后端的时候都需要的情况下才需要放到 Cookie 中。比如登录信息、设置信息之类的。 登录信息不用我说吧?肯定每次请求都要带上。 设置信息,一般比如网站语言(中文、英文之类的),或其他要求后端动态渲染的设置。 **Storage: 这个是新的 API,一般用于在前端缓存一些数据时使用,这些数据一般是只在前端使用,而后端不使用的,所以不用每次都往 后端发送。(或是前端做统计,后端只要一个统计结果之类的) 比如一些网站提供的编辑器,自带草稿功能,每隔几秒钟或几分钟自动保存当前编辑的内容,刷新页面,或是把浏览器关掉重 新打开编辑页面可以自动恢复之前编辑的内容的。 这种信息就适合存放在 **Storage 中。 还有其他的比如 web SQL、IndexedDB 两个数据库,这一般是用来做 HTML 5 应用的时候才会用到的。比如 PWA 或是 HTML5 页游 之类的。(贪玩蓝月跟这没关系(╯‵□′)╯︵┻━┻) 最后说一句:所有逻辑全部都放到前端判断是非常错误的决定! / 因为:前端的一切都是可以手改的啊! 不管是 cookie、localStorage 还是 sessionStorage,只要用户按下 F12,分分钟手改啊! 这个网站要登录?打开 F12,输入 document.cookie=’isLoggedIn=true’; 或者 localStorage.setItem(‘loggedIn’, ‘true’);,你就, 登录成功???喵喵喵? 要设置密码?同样打开 F12 设置点东西。 这些判断放在前端是完全没有意义的啊喂!因为你不管前端判断不判断,都要过一遍后端判断才行啊!!! 充分利用前端,也不能滥用啊喂!!!(╯‵□′)╯︵┻━┻ P.S. 当然,这里我就不提 CSP 之类的网站安全规则了。。。又扯远了。。。