鉴权怎么落地?—— 常见业务场景的方案选型与避坑
给项目加登录,你大概率纠结过这些:个人博客想接"用 GitHub 登录"怎么搞?公司好几个内部系统,能不能登录一次全通?自己做 App 要支持手机号 + 微信 + 邮箱,用户体系怎么设计才不乱?到底是自己搭,还是直接用现成的?
这篇就是一份按场景查的鉴权选型 + 避坑指南:对号入座,拿走方案 + 注意事项。
(本文只讲"怎么选、怎么落地、别踩哪些坑";JWT / OAuth 这些 token 底层怎么工作,我在 上一篇 · 鉴权入门 讲过了——没看也不影响读这篇;遇到不懂的缩写,文末有「名词速查」。)
怎么用这篇
- 先按你的场景对号入座(Part 1),拿走推荐方案 + 注意事项。
- 再看一个绕不开的决策:自己搭还是用第三方(Part 2)。
- 最后对着通用避坑清单(Part 3)过一遍底线。
Part 1 · 按业务场景选方案
场景 1:个人项目 / 博客 / 小工具要登录
- 需求:让用户能登录,但不想自己管密码和注册流程。
- 推荐:接第三方登录(OAuth Authorization Code)——"用 GitHub / 微信 / Google 登录"。你不用存密码、不做找回密码流程,安全交给大厂,用现成库(Auth.js / NextAuth、Passport)几十行就能接。
但不同第三方的接入门槛差很多,选之前先看:
| 第三方 | 接入门槛 |
|---|---|
| GitHub / Google | 注册个 OAuth App 即可,个人开发者免费、几分钟搞定。技术博客 / 个人项目首选。 |
| 微信 | 门槛高、多数要企业资质,个人很难自己接(见下)。 |
微信登录(国内重点,坑最多) —— 它不是一个东西,分场景,门槛各不同:
- PC 网站扫码登录:要 微信开放平台 + 企业资质 + 付费认证审核,个人开发者做不了。
- 公众号 H5 网页登录:要 认证服务号(企业认证,可能需要收费)+ 配网页授权域名(域名得 ICP 备案);授权分两种
scope——snsapi_base(静默,只拿 openid)、snsapi_userinfo(弹窗,能拿头像昵称)。 - 小程序:
wx.login拿 code 换 openid。 - ⚠️ openid vs unionid(最常踩的坑):
openid是用户在单个应用里的 id —— 同一个人在你的公众号和小程序里 openid 不一样!要跨应用认出"是同一个人",必须用unionid(把这些应用绑到同一个微信开放平台账号下)。新手常用错,导致同一用户被当成好几个账号。
Google 登录(海外业务的标配) 海外应用几乎都有"Sign in with Google"(Claude、Notion、Figma… 都用),因为海外用户基本人手一个 Google 账号。
- 技术:标准 OAuth 2.0 + OIDC,在 Google Cloud Console 建 OAuth 凭证(client_id + secret)、配好回调域名即可。
- 门槛比微信低得多:个人开发者就能用、免费、不要企业资质、不要 ICP 备案,几分钟接好。
- Google 是标准 OIDC provider,登录后直接给你一个 id_token(JWT),验签就拿到用户 email / 名字 / 头像。
- ⚠️ 但 Google 在国内可能不可用,用不用它取决于你的用户在哪(见下)。
通用注意:redirect_uri(回调地址)配白名单防开放重定向;第三方返回的唯一 id 存 user_identities 表做关联、支持一个用户绑多个第三方;client_secret 只放服务端(见第一篇)。
选型提示(国内 vs 海外,关键):
- 用户在国内 → 微信(覆盖广但门槛高)、GitHub(开发者向);别用 Google(连不上)。
- 用户在海外 → Google(标配、门槛最低)、GitHub、Apple、Facebook。像 Claude 这种海外 AI 产品,就是 Google + 邮箱打底。
- 想要微信又没资质 → 用 IDaaS(Authing / Auth0)封装,见 Part 2。
场景 2:公司内部多个系统,要统一登录
- 需求:员工登录一次,所有内部系统都通;还要区分管理员 / 普通用户等权限。
- 推荐:SSO 单点登录 + RBAC 权限。
- 怎么做:
- 认证(单点登录):你的系统作为接入方,对接统一身份中心(IdP)。用 OIDC(OpenID Connect,OAuth 2.0 之上的身份认证层、现代 SSO 主流,登录返回 id_token)或 SAML(Security Assertion Markup Language,老牌的、基于 XML 的企业 SSO 标准)。你不存密码,认证委托给 IdP。
- 授权(分权限):RBAC(Role-Based Access Control,基于角色的访问控制)——
用户 → 角色 → 权限。角色可由 IdP 带来(部门 / 组),或在本地管理。
- 注意事项:
- 别自己造 SSO,对接标准协议;验 IdP 签发的 token 用 JWKS(公钥,见第一篇)。
- 权限校验一定在服务端,不是前端藏按钮。
- 权限粒度:先 RBAC 够用,别一上来就上 ABAC(Attribute-Based,基于属性 / 数据范围的更细粒度控制)把自己绕晕。
场景 3:做一个 toC 平台,要手机号 / 邮箱 / 扫码登录
- 需求:你自己就是身份提供方,要支持多种登录方式,统一到一套用户体系。
- 核心设计:「登录方式(identity)与账号(account)解耦」。
users(账号主体) +user_identities(user_id, type, identifier, credential),type= phone / email / wechat。无论哪种方式登录,最终都解析到同一个 user。
各方式的实现要点 + 真实门槛(这里最容易被低估):
① 邮箱登录
最经典的方式。把「用户视角 → 服务端链路」走一遍就懂了(其他方式"拿到身份后签发会话"的链路是共通的,这里讲透):
注册(第一次)
- 用户:输邮箱 + 密码 → 点「注册」。
- 服务端:① 查邮箱是否已注册 → ② 密码用 bcrypt / argon2 哈希后存库(绝不存明文)→ ③ 建用户、标记"未验证" → ④ 生成验证 token、发一封验证邮件(含
verify?token=xxx)。 - 用户:去邮箱点验证链接 → 服务端校验 token → 邮箱标记"已验证"(这步防止拿别人邮箱乱注册)。
登录(之后每次)
- 用户:输邮箱 + 密码 → 点「登录」。
- 服务端:① 按邮箱查用户 → ② 取出库里的密码哈希,
bcrypt.compare(输入, 哈希)比对(不是明文相等)→ ③ 对了 → 签发 access + refresh token(见第一篇)→ ④ 返回 token / 种 HttpOnly Cookie。 - 之后:用户每次请求带 token → 服务端验签放行。
Magic Link(无密码版,体验更好):用户只输邮箱 → 服务端发一次性登录链接 → 用户点 → 服务端验 token(一次性 + 限时)→ 直接签发会话。好处:用户不用记密码、服务端根本不存密码(没有密码泄露风险)。
⚠️ 安全点:登录失败别分"邮箱不存在 / 密码错",统一回"邮箱或密码错误"——否则攻击者能靠它枚举出哪些邮箱注册过。
发信这关的坑(自建必踩):
- 发信要接 SMTP 服务(SendGrid、阿里云邮件推送、Mailgun)——别自建邮件服务器,送达率惨。
- 邮件易进垃圾箱,要给域名配 SPF / DKIM / DMARC(邮件域名认证)提高送达率、防伪造。
② 手机号登录
- 实现:手机号 + 短信验证码(OTP,One-Time Password,一次性验证码)。
- 门槛 / 坑:
- 接短信服务商(阿里云 / 腾讯云短信),短信签名 + 模板要审核(需企业资质,等几天)。
- 每条短信都花钱 → 必须防刷(否则被恶意刷爆,既烧钱又骚扰用户):同手机号 / IP 限频、前置图形验证码 / 滑块;验证码存 Redis、时效 + 一次性。
- 进阶:运营商一键登录(本机号码认证,免输验证码、体验最好,但要接入 + 有成本)。
③ 扫码登录
- 状态机:
待扫描 → 已扫描 → 已确认 / 过期。PC 端轮询、已登录的手机端扫码确认——本质是"用已认证的设备授权一台新设备"。
④ 同设备:Web ↔ 本地 App 协作登录(扫码的"近亲",同一台电脑内完成、不用掏手机)
-
玩法:浏览器网页连上本机已登录的桌面 App,App 确认后网页就登录。
-
两种"桥"(浏览器是沙箱,网页不能直接碰本地程序):自定义协议唤起(
myapp://)、或 本地回环服务(App 监听127.0.0.1:端口、网页用 JS 请求它通信——后者最主流,即 OAuth 原生应用规范 RFC 8252 的 loopback)。 -
⚠️ 安全:任何网页都能连 localhost / 唤起协议,所以 App 端必须校验来源(Origin)+ 弹框让用户确认 + 用一次性 code + PKCE,否则恶意网页能冒名盗登(那个确认弹窗不是多余的)。
-
和扫码的区别:扫码是跨设备、走服务端中转;这个是同设备、走本地通信。本质都是"用已认证的载体授权新载体"。
-
整体注意:验证码防刷是重灾区,务必做;统一登录后签发统一会话凭证(access / refresh,见第一篇);这套自己做工作量大、安全坑多,认真权衡是否直接用第三方(Part 2)。
场景 4:纯前端 / App / 小程序怎么安全鉴权
- 需求:客户端没有"能藏密钥的安全后端"。
- 关键:藏不住 secret,所以——
- 用户登录第三方:Authorization Code + PKCE(Proof Key for Code Exchange,不用 client_secret 也能安全拿 token,见第一篇)。
- token 存哪:Web 优先 HttpOnly Cookie(防 XSS 偷 token);App 用系统安全存储(Keychain / Keystore)。别裸放 localStorage。
- 注意事项:任何 secret 都别打包进前端(能被反编译 / 查看);用 Cookie 要防 CSRF;无论如何都要防 XSS。
场景 5:微服务 / 服务间调用
- 需求:服务 A 调服务 B,怎么证明身份 + 控制权限。
- 推荐:Client Credentials(服务间 token,见第一篇)+ 网关统一鉴权。入口网关验 token、做认证;内部服务各自验 JWT,或信任网关透传的身份。
- 注意事项:secret 走密钥管理别硬编码;别"内网就裸奔信任"——零信任思路,服务间也验;用 RS256 + JWKS,各服务独立验签、签发方独立轮换密钥(见第一篇)。
📌 不同语言的主流库(语言不是障碍)
上面的库以 Node.js 举例,但鉴权是通用的——换个语言,换套库,思路完全一样。常用对照:
| 需求 / 角色 | Node.js | Java | Go |
|---|---|---|---|
| 认证授权框架 | Auth.js(NextAuth)、Passport | Spring Security(中大型主流)、Apache Shiro(轻量) | 无"大一统"框架,靠库组合 |
| 第三方 / OAuth 登录 | Passport、Auth.js | Spring Security(OAuth2 Client) | Goth、golang.org/x/oauth2 |
| 签发 / 验 JWT | jsonwebtoken | jjwt、java-jwt | golang-jwt/jwt |
| 授权 / 权限(RBAC) | node-casbin / 自实现 | Spring Security | Casbin、gorbac |
| 自建 IdP / 授权服务器 | — | Keycloak、Spring Authorization Server | Ory(Hydra / Kratos) |
小注:Go 生态没有像 Spring Security 那样"一统江湖"的框架,习惯是轻量库各管一块(JWT 用 golang-jwt、权限用 Casbin、第三方登录用 Goth)拼起来。这不是缺点,是 Go 的风格。
Part 2 · 自己搭,还是用第三方?(IDaaS)
核心认知先放这:
鉴权是"重要但不差异化"的基础设施,安全坑又深 —— 能用成熟方案,就别从零自己搓。 绝大多数小公司不会自建完整鉴权体系。
第三方身份服务(IDaaS,Identity as a Service,身份即服务)有哪些
- 国外:Auth0(最知名)、AWS Cognito、Firebase Auth、Clerk(开发者友好)、Okta(企业级)。
- 国内:Authing(国内最知名身份云)、阿里云 IDaaS、腾讯云。
- 开源自建:Keycloak(企业级标杆)、Logto、Casdoor(国产)、SuperTokens、Ory。
怎么选(决策表)
| 用第三方 / IDaaS | 自己搭(或开源自建) |
|---|---|
| 团队小、想快速上线 | 有特殊定制、数据要完全自控 |
| 要企业 SSO、社会化登录(含微信)一站式 | 规模大到第三方成本不划算 |
| 鉴权不是核心竞争力(多数业务) | 有专门的安全团队 |
| 不想维护安全(密码 / 防刷 / 合规) | 愿意承担长期安全维护成本 |
中间路线:用开源自建(Keycloak / Logto)——自己部署、数据自控,但不从零写代码。
注意事项:
- 用第三方:评估厂商锁定、数据合规(用户数据存哪、跨境没)、成本随规模增长。
- 自建:你要对密码哈希、防刷、token 安全、漏洞修复全部负责 —— 这是很重的承诺,别低估。
Part 3 · 通用避坑清单(不管哪个场景都要过一遍)
做鉴权前,对着这份安全底线逐条检查:
凭证与密码
- 密码必须哈希(bcrypt / argon2),绝不明文 / 可逆加密。
- client_secret、密钥从密钥管理(KMS / Vault)读,绝不硬编码 / 进 git。
Token
- access token 短命 + refresh 轮转可撤销。
- 别往 JWT 塞敏感信息(明文可解,见第一篇)。
- token 存储:HttpOnly Cookie(Web)/ 安全存储(App),别裸放 localStorage。
接口防护
- 权限校验在服务端(不是前端隐藏按钮)。
- 防越权:水平越权(A 访问 B 的数据)、垂直越权(普通用户调管理员接口)—— 最常见也最致命的漏洞,每个接口都要校验"这个人有没有权访问这条具体资源"。
- 限流防刷:登录、验证码、发短信接口必须限频,防撞库 / 短信轰炸。
- 全程 HTTPS。
运维
- 登录、权限变更要有审计日志。
- 密钥 / secret 支持轮换。
- 注销 / 封禁要能即时生效(无状态 JWT 配黑名单兜底)。
收尾:选型速查表
| 你的场景 | 选这个 |
|---|---|
| 个人项目 / 博客要登录 | GitHub / Google 第三方登录(微信门槛高);用 Auth.js |
| 想要微信登录但没资质 | 用 IDaaS(Authing / Auth0)封装,或先用其他第三方 |
| 公司内部多系统统一登录 | SSO(OIDC)+ RBAC |
| toC 平台、多种登录方式 | 自建 identity / account 解耦,或直接上 IDaaS |
| 纯前端 / App | Authorization Code + PKCE,token 进 HttpOnly Cookie / 安全存储 |
| 微服务互调 | Client Credentials + 网关 + RS256 / JWKS |
| 团队小 / 不想维护安全 | 直接用 Auth0 / Authing / Keycloak |
一句话总结:先问"这个场景的标准方案是什么",再问"自己搭还是用现成的",最后对着避坑清单过一遍。 鉴权不需要你发明轮子,需要你选对轮子、装稳。
附:名词速查
- OAuth 2.0:授权标准,解决"怎么安全地把 token 发给你"。
- OIDC (OpenID Connect):OAuth2 之上的身份认证层,现代 SSO 主流(返回 id_token)。
- SAML:老牌的、基于 XML 的企业 SSO 标准。
- SSO:单点登录,一次登录、多个系统都通。
- RBAC:基于角色的访问控制(用户 → 角色 → 权限)。
- ABAC:基于属性的访问控制,更细粒度(按属性 / 数据范围)。
- IDaaS:身份即服务(Auth0 / Authing 那类第三方身份云)。
- PKCE:让前端 / App 不用 secret 也能安全拿 token 的机制。
- OTP:一次性验证码(短信 / 邮箱那种)。
- openid / unionid:微信里——单应用内的用户 id / 跨应用统一识别同一用户的 id。
- SPF / DKIM / DMARC:邮件域名认证,提高送达率、防伪造。
- IdP:身份提供方(签发身份的一方,如公司身份中心、Google)。
这是「补服务端短板」系列鉴权专题的第二篇。上一篇 《JWT、OAuth、Token 刷新 —— 鉴权入门》 讲机制;这篇讲场景选型与避坑。完整代码与系列都在我的 GitHub:Aimee1608/backend-notes。
评论(0)
登录后参与评论。
还没有评论,来抢沙发吧。

