用户登录方案
分析用户登录的过程。
cookie
简介
cookie本质上只是存储在浏览器中的一小段数据片段,由服务端通过Set-Cookie响应头进行设置。默认同站请求时浏览器会自动携带;是否跨站发送则受 SameSite、Secure、域名与 CORS credentials 等策略约束,并不是绝对“不能跨域”。通过 Domain 可以在同一注册域下的子域间共享(仍受浏览器策略限制)。cookie 由浏览器管理:设置了过期时间则到期清除;未设置 Max-Age/Expires 的会话 cookie 通常在浏览器会话结束时清除。大小一般限制在约 4KB 量级。
用户认证过程
- 服务端在用户登录成功后,将用户认证信息放入在
cookie中并设置过期时间通过set-cookie传回给客户端。 - 在
cookie有效期间,客户端每次请求服务端都会携带cookie,并通过里面的信息完成用户认证。
缺点
- 若把敏感信息直接塞进 cookie,用户仍可通过开发者工具看到内容(
HttpOnly只能阻止 JS 读取,挡不住肉眼与部分攻击面)。 - 大小有限,不适合塞大量数据。
- 若 cookie 里直接存的是无状态凭证本身(例如长寿命 JWT),服务端很难单独吊销;若 cookie 只存
sessionId,删服务端 session 即可失效。也可用Set-Cookie清空 cookie。 - 跨站携带受浏览器策略限制,前后端跨域场景要显式设计
SameSite/ CORS,不能假设“自动带上”。
总结
单纯采用cookie进行用户认证有着诸多缺点,一般都是在session和token方案将cookie作为传递凭证的媒介。
session
简介以及认证过程
session是存储在服务端的用户会话数据,在用户登录成功后,生成一个唯一的sessionId去映射指定的用户信息,并将sessionId通过cookie存储在客户端中,后续客户端的请求自动带上cookie中的sessionId,服务端通过sessionId找到指定的用户信息完成用户的认证。
优点
session由服务端自己进行存储和管理,这也就意味着服务端对用户的登录状态有绝对的控制权。能够通过删除会话记录使用户的登录凭证无效。session存储在服务端,不会受到cookie大小的限制,能够存储较大的数据量。同时只将sessionId传回给客户端,也避免了关键信息的泄漏。
缺点
- 由于
session存储在服务端中,服务器需要花费存储资源去存储、维护用户的会话数据。 - 在项目比较庞大,需要使用多台服务器去均衡负载,
session的管理会比较复杂,需要在多台服务器之间进行同步。
token(JWT)
简介
常见的 JWT(JSON Web Token)默认是 JWS:经签名的、可被解码查看的载荷,不等于加密。签名用于防篡改;若需要保密载荷内容,应使用 JWE 或把敏感数据放在服务端。Token 由服务端签发,客户端携带,服务端校验签名与声明后完成认证。
认证过程
- 用户登录成功后,服务端这边根据用户信息去签发一个
JWT,并将其返回给客户端。 - 客户端拿到
JWT,可存于内存、sessionStorage/localStorage,或通过HttpOnlycookie 下发。跨域场景更常把 Access Token 放请求头;cookie 方案则需配合 CORS 与SameSite设计。 - 服务端拿到
JWT后,解析其中的内容,完成用户的认证。
优点
JWT由服务端进行签发和解析,不需要对用户的会话记录进行存储,减轻服务端的存储压力。并且能够在多台服务器之间保持登录的一致性。JWT本身并不依赖于cookie,针对项目涉及跨域的请求,可以采取将签发的JWT存储在localStorage中,由前端控制把JWT放入到自定义请求头中,从而绕过cookie跨域的限制。
缺点
JWT本身经过签名,存储的信息有限。JWT由服务端进行签发和解析,这个过程会增加服务端的计算压力。JWT一旦签发成功,只能等过期自动失效,服务端不能控制JWT是否失效。
Magic Links(魔法链接)
简介
Magic Links旨在提供一种无需提供密码即可完成的模式,类似的还有手机号获取验证码,不过表现和体验上不一样。一般通过邮件发送登录链接,用户只需点击链接即可完成登录并跳转到相关页面。
认证过程
用户输入邮箱发送登录请求,而服务端这边首先校验用户邮箱是否存在,然后生成一个唯一的token并结合邮箱拼接成一个登录链接。而token则需要服务端通过数据库去管理和维护,并设置一个较短的有效期。在用户使用登录链接完成登录后,token就会立即无效化。
而在用户点击登录链接进行登录时,本质上token就相当于短时间内自动过期的一次性密码,通过邮箱和一次性密码完成登录。

-
identifier:token的验证账号信息,如果使用的是邮箱验证登录,那这个地方的值就是邮箱地址,如果为手机号验证码登录,那这个地方就是手机号 -
token: 生成的token,只能用于与之匹配的identifier -
expires:创建时一般默认比较短的有效期,且当用户使用token登录成功后立即过期无效化