编辑
2026-10-21
编程学习
00

目录

为什么要登录态?
经典登录态方案
HTTP 基本认证
Cookie 和 Session 认证
Token 认证
Refresh Token 和 JWT
SSO 单点登录
基本流程
常见实现方式
SSO 的优点与注意事项
OAuth2 授权
基本角色
授权码模式
Access Token 与 Scope
OAuth 2.0 与登录的关系
第三方登录
基本流程
如何关联第三方账号?
安全注意事项
扫码登录
基本流程
二维码里应该放什么?
手机号一键登录
基本流程
与短信验证码登录的区别
安全注意事项
总结
参考

网上关于登录态的文章数不胜数,公司内部的知识库里也有很多现成的总结。但读别人的文章终究不如自己真正消化一遍,因此我决定结合日常工作和学习,写一篇属于自己的小结。希望能以简洁的方式,把常见的登录态方案梳理一遍,既当复盘,也能方便日后查阅。


拖更太久了,现在的技术文章我都不知道还有没有写的意义了。因为这种总结类的,不产生只搬运知识的文章愈发廉价了,我想不出有什么不用 AI 生成的理由了,空闲时间也愈发得少了,好悲哀……

注意

本文包含 AI 生成内容,已进行人工校对。如有缺漏和错误之处,也欢迎指出!

为什么要登录态?

在互联网应用中,登录态的存在,是为了让系统能够“记住用户是谁”。HTTP 本身是无状态的协议,每一次请求都是独立的,如果没有额外机制,服务器无法区分用户的身份,也就无法提供个性化和安全保障。

引入登录态,主要解决以下几个问题:

  • 身份识别:系统需要确认请求的发起者是谁。例如,A 用户和 B 用户访问同一个购物网站时,服务器必须区分他们的身份,才能返回各自的订单、购物车或账户信息。

  • 权限控制:在多角色系统中,不同用户的权限范围往往不同。比如管理员可以管理用户,而普通用户只能操作自己的数据。登录态让系统能够基于用户身份执行正确的权限校验。

  • 个性化体验:有了登录态,系统可以根据用户的历史行为或偏好,提供定制化的内容与功能,比如推荐商品、记住浏览记录等。

  • 安全性与可追踪性:登录态能够限制未认证用户访问受保护的资源,同时在必要时提供审计和追踪手段,例如记录用户操作日志。

登录态的本质是:在无状态的网络协议之上建立用户与会话的映射关系,从而让应用能识别身份、分配权限,并提供连续一致的使用体验。

经典登录态方案

以下内容参考自:一文搞懂前后端常见登录态方案。

HTTP 基本认证

HTTP 基本认证是 HTTP 协议本身提供了一种服务端对客户端进行用户身份验证的方法。 流程如下:

v2-c38f95b3316518d8766578546a963022_1440w.jpg

  1. 客户端向服务端请求需要登录态的数据
  2. 服务端向客户端返回 401 状态码,要求客户端验证
  3. 客户端根据返回的 WWW-Authenticate: Basic realm="qq.com",弹出用户名和密码输入框要求用户进行验证。
  4. 用户输入用户名和密码后,客户端将用户名及密码以 Base64 格式发送给服务端。
  5. 服务端验证通过后返回用户数据。

这是一种比较简单的验证用户身份的方式,甚至不需要写代码,只要后端服务器配置一下即可。

Cookie 和 Session 认证

Cookie 是客户端请求服务端时,由服务端创建并由客户端存储和管理的小文本文件。Session 则是客户端请求服务端时服务端会为这次请求创建一个数据结构,这个结构可以通过内存、文件、数据库等方式保存。一般来说两者搭配使用,服务端可以根据 Cookie 中的 SessionID 获取到相应的 Session。

v2-43a2b910b2972547f516ef80d539ac6b_1440w.jpg

  1. 客户端向服务端发送认证信息(例如账号密码)
  2. 服务端根据客户端提供的认证信息执行验证逻辑,如果验证成功则生成 Session 并保存,同时通过响应头 Set-Cookie 字段返回对应的 SessionID
  3. 客户端再次请求并在 Cookie 里携带 SessionID。
  4. 服务端根据 SessionID 查找对应的 Session,并根据业务逻辑返回相应的数据。

Token 认证

Token 又叫令牌,是服务端生成用来验证客户端身份的凭证,客户端每次请求都携带 Token。 Token 一般由以下数据组成:

  • uid(用户唯一的身份标识)
  • time(当前时间的时间戳)
  • sign(签名,由 token 的前几位+盐用哈希算法压缩成一定长的十六进制字符串)

image.png

  1. 客户端向服务端发送认证信息(例如账号密码)
  2. 服务端根据客户端提供的认证信息执行验证逻辑(如查询数据库),如果验证成功则生成 Token 并返回。
  3. 客户端存储(可以存在 Cookie、LocalStorage 或本地缓存里)收到的 Token,再次请求时携带 Token(可以通过 HTTP 请求头 Authorization 字段)。
  4. 服务端校验 Token(如查询数据库),并根据业务逻辑返回相应的数据。
认证方式优点缺点
Basic Auth(基础认证)兼容性好,主流浏览器都支持不安全,账号密码仅 Base64 编码,容易被解码;无法主动注销,除非关闭标签页或浏览器
Cookie & SessionCookie 由客户端管理,支持设定有效期、安全加密、防篡改、请求路径等属性;Session 由服务端管理,支持有效期,可以存储各种数据Cookie 只能存储字符串,大小和数量有限制,对移动端支持不好,存在跨域限制;Session 占用服务端资源,客户端量大时影响性能;集中存储(如 Redis)增加部署维护成本
Token(如 JWT)客户端可存储在 Cookie、LocalStorage 等,服务端无需存储;安全性高(签名校验);支持移动端;支持跨域Token 比较大,占用传输带宽;每次签名校验增加服务端开销;有效期通常较短,需要刷新机制

Refresh Token 和 JWT

为了避免被盗用 Token 一般有效期比较短。但是有效期太短会造成客户端不断重新登录,体验太差。因此我们可以再来一个 Token,一个专门生成 Token 的 Token,称为 Refresh Token。

image.png

  1. 客户端向服务端发送认证信息(例如账号密码)
  2. 服务端根据客户端提供的认证信息执行验证逻辑(如查询数据库),如果验证成功则生成 Token 和 Refresh Token 并返回。
  3. 客户端存储(可以存在 Cookie、LocalStorage 或本地缓存里)收到的 Token 和 Refresh Token,再次请求时携带 Token(可以通过 HTTP 请求头 Authorization 字段)。
  4. 服务端校验 Token(如查询数据库),并根据业务逻辑返回相应的数据。
  5. 服务端发现 Token 过期了,拒绝了请求。
  6. 客户端重新请求并携带 Refresh Token。
  7. 服务端校验 Refresh Token 并返回新 Token 和新 Refresh Token。
  8. 客户端再次请求并携带新 Token。

注意

后续文本包含 AI 生成内容,已进行人工校对

此外,服务端校验客户端发过来的 Token 时,可能需要查询数据库,以确认 Token 是否有效、用户是否仍然可用等。如果每次请求都访问数据库,会带来额外的性能开销。

一种优化方式是使用 JWT(JSON Web Token)。JWT 是一种 Token 格式,可以将用户 ID、过期时间等声明放在 Token 中,并通过数字签名保证这些内容未被篡改。JWT 通常由三部分组成:Header(头部)、Payload(负载)和 Signature(签名),中间用点(.)分隔。 这样,服务端可以通过验证签名、检查过期时间等方式,在不查询数据库的情况下完成基本校验,从而减少数据库访问。

但这并不意味着使用 JWT 后就一定不需要查询数据库:如果业务需要检查用户是否被禁用、权限是否已变更,或者 Token 是否已被主动撤销,仍然可能需要额外的查询或其他机制。

SSO 单点登录

SSO(Single Sign-On,单点登录)是一种身份认证机制,核心目标是:用户只需要登录一次,就可以访问多个相互信任的应用,而不需要在每个应用中重复登录。

例如,公司内部有 OA、代码托管平台、项目管理系统等多个应用。如果没有 SSO,用户可能需要分别登录这些系统;接入 SSO 后,用户登录统一认证中心,就可以在访问其他应用时复用已有的登录状态。

这里需要注意,SSO 并不是一种独立的 Token 格式,而是一套跨应用共享认证结果的机制。它可以结合 Cookie、Session、Token 等技术实现。

基本流程

假设有三个角色:

  • 用户:发起访问的浏览器。
  • 应用 A:用户最先访问的业务系统。
  • 认证中心:统一负责用户身份认证的系统。
  • 应用 B:用户随后访问的另一个业务系统。

典型流程如下:

  1. 用户访问应用 A,但应用 A 发现用户尚未登录。
  2. 应用 A 将用户重定向到认证中心,并携带应用自身的回调地址等参数。
  3. 认证中心检查自己的登录状态。如果用户尚未登录,则要求用户进行身份验证;如果已经登录,则可以直接继续。
  4. 认证成功后,认证中心向应用 A 返回一个用于完成认证流程的凭证,应用 A 验证凭证后建立自己的本地登录态。
  5. 用户访问应用 B 时,应用 B 同样将用户引导至认证中心。
  6. 由于用户已经登录认证中心,通常不需要再次输入账号密码。认证中心为应用 B 完成相应的认证流程,应用 B 验证结果后建立自己的本地登录态。

因此,SSO 并不意味着多个应用直接共享同一个 Session 或 Cookie。更常见的做法是:认证中心维护统一的登录状态,各业务应用分别建立自己的本地会话,通过可信的认证流程建立关联。

常见实现方式

一种常见的实现方式是基于共享域 Cookie。例如,多个业务系统部署在同一个主域名下,可以在满足浏览器 Cookie 规则和安全要求的前提下,共享特定域的 Cookie。但这种方式耦合较强,不适用于所有跨域场景。

另一种更通用的方式是通过认证中心完成重定向认证。业务应用不需要直接读取认证中心的 Cookie,而是通过跳转、回调以及凭证验证来确认用户身份。这种方式更适合多个独立应用,也可以基于 OAuth 2.0 / OpenID Connect 等标准协议实现。

SSO 的优点与注意事项

  • 用户体验更好:用户只需完成一次主要的身份验证,就能访问多个业务系统。
  • 便于统一管理:可以集中处理登录策略、多因素认证、账号状态和认证审计。
  • 降低重复建设成本:业务应用不必各自实现完整的身份认证流程。
  • 需要处理统一退出:用户退出认证中心,并不一定会自动清除所有业务应用已经建立的本地会话,需要额外设计单点注销或会话失效机制。
  • 认证中心成为关键基础设施:一旦认证中心不可用,新的登录流程可能受到影响;如果认证中心被攻破,影响范围也可能更大。

SSO 解决的是多个应用之间的登录体验和认证协同问题,而 OAuth 2.0 主要解决授权问题。两者可以配合使用,但概念并不相同。

OAuth2 授权

OAuth 2.0 是一种授权框架,用于让第三方应用在获得用户授权后,访问用户在某个服务中的受保护资源,而不需要直接获取用户的账号密码。

例如,一个图片管理应用希望读取用户网盘中的照片。传统做法可能是让用户直接向第三方应用提供网盘账号密码,这不仅风险高,也无法精细控制第三方应用能够执行的操作。

OAuth 2.0 则允许用户在网盘的授权页面确认授权范围,由网盘向第三方应用签发访问令牌。第三方应用凭借该令牌访问允许访问的资源,而不需要知道用户的网盘密码。

基本角色

OAuth 2.0 定义了几个核心角色:

  • Resource Owner(资源所有者):通常是用户,也是有权授权访问受保护资源的一方。
  • Client(客户端):代表用户发起授权请求的应用,例如第三方图片管理应用。
  • Authorization Server(授权服务器):负责处理授权请求、验证用户身份、获取用户授权并签发令牌。
  • Resource Server(资源服务器):保存受保护资源,并根据访问令牌判断请求是否有权访问。

授权服务器与资源服务器可以由同一套系统提供,也可以是相互独立的服务。

授权码模式

目前,Web 应用中常见的授权流程是 Authorization Code Grant(授权码模式)。下面以第三方应用访问网盘资源为例说明。

  1. 用户在第三方应用中点击“绑定网盘账号”。
  2. 第三方应用将用户重定向到网盘的授权页面,并携带客户端标识、回调地址、申请的权限范围 scope、随机参数 state 等信息。
  3. 网盘验证用户身份,并让用户确认是否授权第三方应用访问指定资源。
  4. 用户同意授权后,网盘将浏览器重定向回第三方应用的回调地址,并附带一个临时授权码 code。
  5. 第三方应用的后端使用授权码向授权服务器的令牌端点请求 Access Token;在启用 PKCE 的流程中,还需要提供对应的 code_verifier。
  6. 授权服务器验证授权码、客户端身份(适用时)、回调地址以及 PKCE 等条件,验证通过后签发 Access Token,必要时也会签发 Refresh Token。
  7. 第三方应用使用 Access Token 请求资源服务器,资源服务器验证令牌及其权限后返回允许访问的数据。

这里的关键是:浏览器回调传递的是授权码,而不是直接把用户密码交给第三方应用。 授权码通常具有短有效期,并且只能使用一次;Access Token 则用于访问受保护资源。

在实际开发中,应使用精确匹配的回调地址,并通过 state 等机制防范请求伪造。对于授权码流程,尤其是无法安全保存客户端密钥的公开客户端,应使用 PKCE(Proof Key for Code Exchange)来降低授权码被截获或注入后遭到滥用的风险。现代 OAuth 安全实践也推荐在授权码流程中使用 PKCE。

Access Token 与 Scope

Access Token 是客户端访问受保护资源的凭证。它可以是不透明的随机字符串,也可以采用 JWT 等格式,具体取决于授权服务器的设计。

scope 用于表达客户端申请或获得的授权范围。例如:

  • profile:read:读取用户资料。
  • photo:read:读取照片。
  • photo:write:修改照片。

这些名称只是示例,实际权限名称由具体系统定义。资源服务器必须根据实际签发的权限执行校验,不能仅因为客户端携带了一个有效令牌,就允许它访问所有资源。

OAuth 2.0 与登录的关系

需要特别区分的是:OAuth 2.0 主要解决授权,不直接定义统一的用户身份认证协议。

假设某个第三方应用获得了网盘的 photo:read 权限,这只能说明它获得了访问照片的授权,并不能单凭这个事实,就断定当前登录该第三方应用的用户是谁。

如果需要基于第三方身份提供“使用某账号登录”的能力,通常会使用 OpenID Connect(OIDC)。OIDC 在 OAuth 2.0 之上增加了身份认证层,并通过 ID Token 等机制向客户端提供经过验证的用户身份信息。

因此,可以简单记为:

  • OAuth 2.0:授权,即允许应用访问哪些资源。
  • OpenID Connect:身份认证,即确认用户是谁。
  • Access Token:用于访问受保护资源。
  • ID Token:在 OIDC 流程中用于向客户端传递身份认证相关信息。

这也是为什么接入第三方登录时,不能只看到 OAuth 2.0 和 Access Token 就认为整个身份认证流程已经完成。

第三方登录

第三方登录是指应用允许用户使用其他平台已有的账号完成登录,例如使用微信、QQ、GitHub 或 Google 账号登录,而不必为当前应用重新注册一套账号密码。

从实现角度看,第三方登录通常会借助 OAuth 2.0 或 OpenID Connect 等协议,但不同平台提供的接口、授权流程和用户信息获取方式可能有所差异。

基本流程

以用户使用第三方平台账号登录某个网站为例:

  1. 用户点击“使用第三方账号登录”。
  2. 网站将用户重定向到第三方平台的授权或认证页面。
  3. 用户在第三方平台完成登录,并确认相应授权。
  4. 第三方平台将用户重定向回网站,并返回授权码或平台规定的认证结果。
  5. 网站后端根据平台协议交换令牌,并在需要时获取经过验证的用户身份信息。
  6. 网站根据第三方平台返回的稳定用户标识,查询本地账号是否已绑定该身份。
  7. 如果已经绑定,则登录对应的本地账号;如果尚未绑定,则根据产品策略引导用户注册、绑定已有账号或完成其他必要步骤。
  8. 网站建立自己的登录态,并向用户提供正常的业务服务。

需要注意,第三方平台的身份与本地业务账号并不是同一个概念。第三方平台负责证明用户在该平台上的身份,而当前应用仍然需要管理自己的用户、权限和会话。

如何关联第三方账号?

通常不建议直接使用昵称、头像或邮箱作为唯一关联依据,因为这些信息可能重复、变更,或者无法被可靠验证。

更稳妥的做法是保存第三方平台标识和该平台提供的稳定用户 ID,例如:

(provider, provider_user_id) -> local_user_id

其中,provider 表示第三方平台,provider_user_id 表示用户在该平台内的唯一标识,local_user_id 则是当前应用自己的用户 ID。

对于支持多个应用或多个开发者账号的平台,还需要考虑用户标识的作用域。例如,某些平台的用户 ID 只在特定应用或开发者范围内唯一,不能脱离对应的应用标识直接使用。

安全注意事项

  • 不要让第三方应用直接收集用户的第三方账号密码。
  • 验证回调流程,正确使用 state,并在适用时使用 PKCE。
  • 通过官方接口验证令牌和用户身份,不要仅凭客户端传回的昵称、头像或用户 ID 就认定登录成功。
  • 将第三方账号绑定和本地账号登录分开处理,避免未经验证的自动绑定导致账号被接管。
  • 第三方登录成功后,仍应由当前应用建立自己的登录态,并执行本地权限校验。

第三方登录主要解决的是身份来源问题:用户可以借助已有账号证明自己的身份,但当前应用仍然需要决定如何将这个身份映射到自己的用户体系中。

扫码登录

扫码登录是指用户通过手机等已登录设备扫描网页上的二维码,从而完成另一个设备或客户端的登录。它常见于网页版即时通信软件、电视应用、开发者工具等场景。

扫码登录并不是一种独立的认证协议,而是一种交互方式。二维码背后可以采用一次性票据、设备配对、临时授权码等机制来实现身份确认。

基本流程

以电脑浏览器登录某个应用为例:

  1. 用户打开登录页面,服务端为本次登录流程创建一个临时会话,并生成一个具有随机性、短有效期的二维码凭证。
  2. 网页展示二维码,并通过轮询、长轮询或 WebSocket 等方式查询登录状态。
  3. 用户使用手机扫描二维码,手机应用识别出本次登录请求,并向服务端提交扫码确认。
  4. 如果手机尚未登录,则需要先完成手机端的身份认证。
  5. 手机端向用户展示登录目标及必要信息,用户确认后,服务端将本次登录流程标记为已授权。
  6. 网页端检测到授权完成后,通过受保护的流程获取登录结果。
  7. 服务端为浏览器建立新的登录会话,或向客户端签发相应的认证凭证,完成登录。

实际系统可能会将流程拆分成“待扫码”“已扫码待确认”“已确认”“已过期”等状态。扫码与确认是两个不同的步骤:仅仅扫描二维码,并不一定意味着用户已经同意登录。

二维码里应该放什么?

二维码中通常不应该直接包含用户的长期登录 Token、账号密码或其他可长期使用的敏感凭证。

更合理的设计是放入一个随机、不可预测、具有短有效期的临时标识。服务端将它与本次登录会话关联,并在收到手机端的授权确认后更新状态。

这样,即使有人截取了二维码,也不应当仅凭二维码内容就能够直接获得长期登录权限。

此外,还应注意以下问题:

  • 防止二维码被盗用:二维码应具有短有效期和足够的随机性,并在完成后失效。
  • 防止登录确认被劫持:手机端应清晰展示正在登录的设备或目标,并要求用户明确确认。
  • 避免重复消费:确认和兑换过程需要保证一次性,防止同一临时凭证被重复使用。
  • 限制轮询与状态查询:避免通过临时标识枚举或探测其他人的登录流程。
  • 保护登录结果:最终的会话凭证必须通过可信的渠道交付给目标客户端,不能仅因为某个二维码状态变成“已确认”就允许任意请求方获得登录态。

扫码登录的本质,是利用已经完成身份认证的设备,为另一个设备发起的登录请求进行授权。它改变的是用户确认身份的交互方式,而不是取消服务端对身份和权限的验证。

手机号一键登录

手机号一键登录是一种利用运营商提供的号码认证能力,简化用户登录或注册流程的方式。用户通常只需要点击确认按钮,就可以在满足运营商和客户端环境要求的情况下,完成手机号验证,而不必手动输入短信验证码。

传统短信验证码登录与手机号一键登录的区别在于:前者通常要求用户接收并输入短信中的验证码;后者则由运营商或号码认证服务商提供相应的验证能力,应用通过服务端接口验证结果。

基本流程

image.png

  1. 用户在应用中选择手机号一键登录。
  2. 客户端调用运营商或号码认证服务商提供的 SDK,完成必要的网络和设备环境检查。
  3. SDK 获取本次认证所需的临时凭证,并展示手机号授权确认界面。
  4. 用户确认后,客户端将临时凭证提交给应用后端。
  5. 应用后端调用可信的号码认证服务接口,校验凭证的有效性,并获取或验证对应的手机号。
  6. 应用根据经过验证的手机号查询本地用户。如果用户已存在,则建立登录态;如果用户不存在,则根据业务规则创建账号或引导用户完成注册。
  7. 应用向客户端返回自己的登录结果。

具体实现取决于运营商和服务商提供的 SDK 与接口。有些方案会先通过客户端 SDK 获取临时 token,再由后端向服务商换取认证结果;有些方案的流程则有所不同。

与短信验证码登录的区别

对比项短信验证码登录手机号一键登录
用户操作接收并输入验证码通常点击确认即可
验证方式校验短信验证码调用运营商或号码认证服务验证
用户体验操作步骤较多操作更便捷
依赖条件能接收短信即可取决于运营商、SDK、设备及网络环境
成本与接入需要短信发送与验证服务通常需要接入号码认证服务,可能产生相应费用

安全注意事项

  • 手机号认证成功不等于用户已经完成当前应用的登录。应用仍需完成本地账号映射、权限检查和登录态创建。
  • 应由服务端验证认证结果,不能只相信客户端提交的手机号。
  • 临时凭证应具有短有效期,并与本次认证流程绑定,防止重放和跨流程使用。
  • 应考虑手机号换号、号码回收以及账号绑定冲突等问题。手机号可能发生变化,不宜在所有业务场景中作为永久不变的用户身份标识。
  • 对高风险操作,不能只依赖手机号认证,应根据风险增加二次验证或其他安全措施。

手机号一键登录主要改善的是用户输入和身份验证的体验。它并不会替代应用自身的用户体系,也不意味着手机号可以永久代表某个自然人。

总结

回过头来看,这些登录态方案其实解决的是不同层面的问题。

  • HTTP Basic Auth 提供了简单的 HTTP 身份认证机制。
  • Cookie + Session 通过客户端 Cookie 与服务端会话建立登录态。
  • Token 为客户端提供访问凭证,JWT 则是一种可以携带声明并通过签名验证的 Token 格式。
  • Refresh Token 用于在一定条件下获取新的 Access Token,减少用户重复登录的次数。
  • SSO 解决多个应用之间如何复用认证结果的问题。
  • OAuth 2.0 解决第三方应用如何在获得授权后访问受保护资源的问题,OIDC 则在此基础上提供身份认证能力。
  • 第三方登录、扫码登录和手机号一键登录,则更多关注用户如何完成身份验证,以及如何将验证结果转换成当前应用的登录态。

它们并不处于同一个层级,因此实际系统经常会组合使用多种机制。例如,用户通过 OIDC 完成第三方登录,应用再通过 Cookie + Session 维护自己的登录态;或者使用 OAuth 2.0 授权码流程获取访问令牌,再通过 Refresh Token 续期。

真正设计登录态时,除了考虑流程是否能够跑通,还需要关注凭证的存储、传输、过期、撤销、权限范围以及被盗用后的影响。登录成功只是身份认证的开始,如何安全地维持和管理登录状态,才是登录态设计的核心。

参考

本文作者:Zerol Acqua

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!