关于前端:登录鉴权-cookiesession和token的实现和区别

1次阅读

共计 2824 个字符,预计需要花费 8 分钟才能阅读完成。

前言:
本文中的用户端 (client) 约等于浏览器。
服务端就是 sever。

cookie、session、token 都是由 sever 生成,保留在 client 端。
三者最大的不同在于服务端对 cookie、session、token 的解决。

cookie
1、在 client 输出账号密码,点击登录发送申请 a 到 sever,sever 验证账号密码通过,获知用户信息。
2、这个时候 sever 生成 cookie,在申请 a 的 response 中用 Set-Cookie 字段把 cookie 信息返回给发送申请的 client。client 见到 Set-Cookie 之后把 cookie 记录在本地。
3、client 再次发送申请 b 的时候会携带 cookie,让 sever 晓得这个申请的发起者的身份(或者权限)。

session
1、在 client 输出账号密码,点击登录发送申请 a 到 sever,sever 验证账号密码通过,获知用户信息。
2、这个时候 sever 生成有对应关系的 key 和 value。value 中保留用户信息 (下文用 userMessage 指代),userMessage 须要存储在服务器端(个别是保留在内存数据库中,这样查的快)。key 是一长串无序字符串,这里的 key(下文用 sessionString 指代) 就是 session。
3、sessionString 作为 cookie 的一部分发送给 client,cookie 的内容中由 sever 增加一个非凡的字段 (字段名能够是 session、sessionId、sys_session 等等),这个字段用于传输和存储 sessionString(举例: 非凡字段名 a_sys_session 对应 sessionString)。
在申请 a 的 response 中用 Set-Cookie 字段把 cookie 信息返回给发送申请的 client,client 见到 Set-Cookie 之后把 cookie 记录在本地,a_sys_session 和 sessionString 也被记录在本地。
4、client 再次发送申请 b 的时候会携带 cookie,cookie 中又有 a_sys_session 字段,当 sever 拿到 cookie 后,从 cookie 中提取出 a_sys_session 字段对应的 sessionString。
5、通过 sessionString 查问 userMessage,获取用户信息(也有可能查问不到,如过期了,或者 sessionString 被改了)。获取用户信息之后,sever 晓得这个申请的发起者的身份(或者权限)。

token
1、在 client 输出账号密码,点击登录发送申请 a 到 sever,sever 验证账号密码通过,获知用户信息。
2、sever 将用户信息 (下文用 userMessage2 指代) 拿进去格式化为一种特定的格局 (如 string、object)。sever 本身须要有一个秘钥(下文用 secretKey 指代),这个秘钥保留在服务器端,将 userMessage2 和 secretKey 通过加密算法(createFunction) 生成一段新的字符串 (下文用 secretString2 指代)。将 userMessage2 和 secretString2 通过某种易拆分的形式加工成一个新字符串(concatString2),这里的 concatString2 就是 token。sever 端无需保留 token。
3、concatString2 须要返回给 client,这时是有两种形式可选的。
3.1 其一是作为 cookie 的一部分发送给 client。cookie 的内容中由 sever 增加一个非凡的字段(字段名能够是 token、sys_token 等等),这个字段用于传输和存储 concatString2(举例: 非凡字段名 a_sys_token 对应 concatString2)。
在申请 a 的 response 中用 Set-Cookie 字段把 cookie 信息返回给发送申请的 client,client 见到 Set-Cookie 之后把 cookie 记录在本地,a_sys_token 和 concatString2 也被记录在本地。client 再次发送申请 b 的时候会通过 cookie 携带 token 信息。

3.2 其二是作为特定的返回字段交给 client 自行存储。这种状况下 token 须要在客户端接管到申请 a 的 response 之后用程序实现将 token 存储到 sessionStorage 或 localStorage 中。另外每次发送申请时都须要将 token 携带上,传递给 sever。这种状况下携带 token 信息的形式的通用做法是将 token 放在申请头的 Authorization 字段。

4、client 再次发送申请 b 的时候携带 token 信息达到 sever 后,sever 解析失去 concatString2,再通过 concatString2 拆分出 userMessage2 和 secretString2。
5、通过解析失去的 userMessage2 加上服务端保留的 secretKey+createFunction 从新生成 newSecretString,校验 newSecretString 和 secretString2 是否统一。如果校验通过,则确认 userMessage2 是正确的用户信息。

三者安全性比照:
cookie 的安全性最差,因为 cookie 把用户信息放在了本地,可能会被批改。尽管咱们能够通过设置 httpOnly 禁止通过 js 代码改变 cookie,但如果从浏览器中复制 cookie,再批改 cookie 用 http 工具 (如 postman) 发送申请,是有可能获取到额定的信息的。
session 把用户信息存储在的 sever 端,token 有校验的过程,两者的安全性远强于 cookie。session 和 token 的安全性在同一级别,硬要分个高下我感觉 session 稍强。但要说能改 token 的信息,那必须同时获知创立 token 的 secretKey 和 createFunction,这也得是有内鬼才行吧。

session 和 token 的优劣势剖析:
因为 sever 可能对接大量的 client,也就须要寄存大量的 session,这样会导致数据库的 IO 压力,要思考用户数量。此外如果服务器端是一个集群,为了同步登录态,须要将 session 同步到每一台机器上,无形中减少了 sever 的保护老本。
token 的劣势在于服务器端不须要存储 token,所以不会对服务器端造成额定的存储压力,即便是服务器集群,也不须要减少保护老本。
token 的实现形式较为灵便,前端有很多施展空间,不肯定要保留在 Cookie 中。
token 下发之后,只有在失效工夫之内,就始终无效,如果服务器端想发出此 token 的权限,并不容易。(token 的做法我没实际过,不晓得有什么形式能够发出 token 权限,盲区)

完结。

同步更新到本人的语雀
https://www.yuque.com/diracke…

正文完
 0