找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3323

积分

0

好友

439

主题
发表于 7 小时前 | 查看: 4| 回复: 0

现在几乎所有的App都支持多个第三方账号登录(微信、QQ、微博等),这就是多账号统一登录。账号表设计与流程设计如果不到位,后续扩展会非常困难。

本文不提供具体的代码实现,而是结合我在公司负责账号模块的实践经验,梳理一套通用的设计思路,供大家参考。

一、自建的登录体系

1.1 手机号登录注册

思路:每个手机号对应一个用户,手机号为必填项。

流程

  1. 用户输入手机号,发送到服务端。服务端先判断该手机号是否存在账号;如果没有,则生成随机验证码,将手机号和验证码绑定到 Redis,并设置过期时间(通常5分钟),然后将验证码通过短信发送给用户。
  2. 用户收到验证码后,在界面填写验证码、密码等基础信息,提交到服务端。服务端验证 Redis 中该手机号对应的验证码是否一致——不一致则返回错误码;一致则创建账号并保存密码。
  3. 注册成功后,用户可通过 手机号+密码 登录。

问题

  • 用户体验差:需要获取验证码、填写验证码/密码/用户名等大量信息才能完成注册。
  • 容易遗忘密码:忘记后只能通过“忘记密码”重新设置。

1.2 优化注册登录

思路:弱化密码的必填性,无论用户是否注册过,均可通过 手机号+验证码 直接登录(同时保留 手机号+密码 方式)。

流程

  1. 输入手机号,发送到服务端。服务端生成随机验证码,绑定到 Redis 并设置过期时间,通过短信发送。
  2. 用户填写收到的验证码,提交到服务端。服务端验证验证码是否一致——失败则返回错误码;成功则直接登录。如果是老用户,拉取用户信息;如果是新用户,提示可完善信息(不强制)。
  3. 用户通过 手机号+验证码 登录后,也可选择设置密码,以后即可使用 手机号+密码 登录。密码变为非必填项。

用户表设计

用户表结构:id, user_name, user_password, user_mobile, state, more

1.3 引入第三方账户方案

1.3.1 微博登录

进入 Web2.0 时代,微博开放了第三方网站登录。产品要求:用户能用微博账号登录我们的 App,并且和自有用户表关联。

流程

  1. 客户端调用微博登录界面,用户输入用户名、密码,登录成功后返回 access_token。通过 access_token 调用 API 接口获取用户信息。
  2. 服务端根据用户信息在用户表中创建一个账号。此后,该第三方账号即可直接通过微博登录。

微博用户信息表设计

微博用户表结构:id, user_id, uid, access_token

1.3.2 噩梦来临

紧接着,QQ、微信、网易等纷纷开放用户登录。如果按照“微博用户信息表”的方式为每家新建一张表、写一套登录逻辑,扩展性会变得非常糟糕。

二、优化账号体系

2.1 原账号体系分析

  • 自建登录体系:无论是 手机号+密码 还是 手机号+验证码 ,本质上都是 用户信息+密码 的验证形式。
  • 第三方登录:也是 用户信息+密码 的形式——用户信息是第三方系统中的唯一标识(ID),密码则是 access_token(一种有使用时效、定期修改的密码)。

2.2 新的账号体系

2.2.1 数据表设计

用户基础信息表

用户基础信息表:id, nickname, avatar, more

用户授权信息表

用户授权信息表:id, user_id, identity_type, identifier, credential

说明

  • 用户表拆分为 用户基础信息表 + 用户授权信息表
  • 用户信息表不保存任何密码或登录信息(如用户名、手机号、邮箱),只保留昵称、头像等基础信息。所有与授权相关的内容都放在用户授权信息表中,用户信息表和用户授权信息表是一对多的关系

2.2.2 登录流程

  • 手机号+验证码:沿用之前的方案。
  • 邮箱/手机号+密码:用户填写 邮箱/手机号+密码;请求登录时,先判断类型。以手机号登录为例:使用 type='phone' 结合 identifier='手机号' 查找,取出并判断 password_hash(密码)是否与当前条目的 credential 相符,相符则通过验证,然后通过 user_id 获取用户信息。
  • 第三方登录(如微信登录):查询 type='weixin' 结合 identifier='微信 openId'。如果有记录,则直接登录成功并更新 token;在假设与微信服务器通信不被劫持的情况下,无需判断凭证问题。

2.2.3 优缺点

优点

  1. 登录类型便于扩展,新增登录类型的开发成本显著降低。
  2. 原来需要验证手机号/邮箱是否已验证时,需要额外字段(如 phone_verifiedemail_verified);现在只需在用户授权信息表中增加一个统一的 verified 字段,每种登录方式均可直观显示验证状态。
  3. 在用户授权信息表中添加时间和 IP 地址,可以更完整地跟踪用户使用习惯(例如:已不再使用微博登录两年多、已绑定微信 300 天)。
  4. 邮箱和手机号仍可保留在 users 表中,但只作为“展示用途”,与昵称、头像等属性本质相同。
  5. 可按需绑定任意数量的同类型登录方式(如一个用户可绑定多个微信、多个邮箱、多个手机号)。当然也可以限制每种登录方式只能有一条记录。

缺点

  1. 当用户同时拥有邮箱、用户名、手机号等多种站内登录方式时,修改密码必须统一修改,否则会出现 邮箱+新密码手机号+旧密码 都能登录的矛盾情况。
  2. 代码量和逻辑判断增加,复杂度上升。例如:无论用户是否已登录、是否已注册,都通过同一链接前往微博第三方授权后返回,可能产生多种分支情况:
    • 该微博在本站未注册过:直接注册关联并登录。
    • 该微博已在本站存在,当前用户未登录:直接登录成功。
    • 该微博未在本站注册,但当前用户已登录且已关联另一个微博账号:处理方式取决于是否允许绑定多个微博账号。
    • 该微博未在本站注册过,当前用户已登录:尝试进行绑定操作。
    • 该微博已注册,用户又使用该账号登录:为何重复绑定自己?
    • 该微博已存在,但当前用户已登录且关联的是另一个微博账号:如何处理?

三、一键登录

3.1 背景

回顾 手机号+验证码 的登录方式:

  1. 输入手机号、等待验证码短信、输入验证码、点击登录,整个流程可能需要 20 秒以上,操作繁琐。
  2. 依赖短信网络,若收不到短信则无法登录。
  3. 存在验证码泄漏风险——有人知道你的手机号并窃取验证码,就能登录你的账号。

那么,我们为什么需要验证码?验证码的作用是确认该手机号属于你。除了短信,是否还有其他认证方式?

  • 如果能获取当前使用的手机号,就能直接验证。但出于安全考虑,客户端无法直接获取手机号,运营商可以通过 SIM 卡数据查询到。
  • 现在运营商已开放相关能力:用户输入手机号后,调用运营商的接口判断输入的手机号是否与本地号码一致。这样用户就无需等待验证码短信,不受短信网络限制。
  • 更进一步,如果运营商能直接把当前号码返回给应用,用户连手机号都不需要填写了。

这就是 一键登录

3.2 本机号码认证

获取当前手机使用的 SIM 卡号,直接使用该号码登录,即为一键登录。

这种方式的优势显而易见:将原本可能 20 秒的流程缩短至 2 秒左右,极大提升用户体验。

主要步骤

  1. SDK 初始化:调用 SDK 的初始化方法,传入项目在平台上的 AppKey 和 AppSecret。
  2. 唤起授权页:调用 SDK 唤起授权接口。SDK 先向运营商发起获取手机号验码的请求,请求成功后跳转到授权页。授权页会显示手机号掩码以及运营商协议供用户确认。
  3. 同意授权并登录:用户同意协议并点击授权页的登录按钮,SDK 请求本次取号的 token,请求成功后返回 token 给客户端。
  4. 取号:客户端将获取到的 token 发送到自己的服务器,服务器携带 token 调用运营商的一键登录接口,成功则返回手机号码。服务器用该手机号进行登录或注册操作,返回结果给客户端,完成一键登录。

四、小结

没有最好的方案,只有最适合当前系统的设计。不必深究孰优孰劣,鞋合不合脚只有脚知道。

如果您对账号体系设计有不同的思路或经验,欢迎在 云栈社区 一起交流探讨。




上一篇:蚂蚁集团第四次分红方案出炉 前两次累计超438亿元
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-27 10:12 , Processed in 0.745569 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表