















给项目加登录,你大概率纠结过这些:个人博客想接"用 GitHub 登录"怎么搞?公司好几个内部系统,能不能登录一次全通?自己做 App 要支持手机号 + 微信 + 邮箱,用户体系怎么设计才不乱?到底是自己搭,还是直接用现成的?
这篇就是一份按场景查的鉴权选型 + 避坑指南:对号入座,拿走方案 + 注意事项。
(本文只讲"怎么选、怎么落地、别踩哪些坑";JWT / OAuth 这些 token 底层怎么工作,我在 上一篇 · 鉴权入门 讲过了——没看也不影响读这篇;遇到不懂的缩写,文末有「名词速查」。)
但不同第三方的接入门槛差很多,选之前先看:
| 第三方 | 接入门槛 |
|---|---|
| GitHub / Google | 注册个 OAuth App 即可,个人开发者免费、几分钟搞定。技术博客 / 个人项目首选。 |
| 微信 | 门槛高、多数要企业资质,个人很难自己接(见下)。 |
微信登录(国内重点,坑最多) —— 它不是一个东西,分场景,门槛各不同:
scope——snsapi_base(静默,只拿 openid)、snsapi_userinfo(弹窗,能拿头像昵称)。wx.login 拿 code 换 openid。openid 是用户在单个应用里的 id —— 同一个人在你的公众号和小程序里 openid 不一样!要跨应用认出"是同一个人",必须用 unionid(把这些应用绑到同一个微信开放平台账号下)。新手常用错,导致同一用户被当成好几个账号。Google 登录(海外业务的标配) 海外应用几乎都有"Sign in with Google"(Claude、Notion、Figma… 都用),因为海外用户基本人手一个 Google 账号。
通用注意:redirect_uri(回调地址)配白名单防开放重定向;第三方返回的唯一 id 存 user_identities 表做关联、支持一个用户绑多个第三方;client_secret 只放服务端(见第一篇)。
选型提示(国内 vs 海外,关键):
- 用户在国内 → 微信(覆盖广但门槛高)、GitHub(开发者向);别用 Google(连不上)。
- 用户在海外 → Google(标配、门槛最低)、GitHub、Apple、Facebook。像 Claude 这种海外 AI 产品,就是 Google + 邮箱打底。
- 想要微信又没资质 → 用 IDaaS(Authing / Auth0)封装,见 Part 2。
用户 → 角色 → 权限。角色可由 IdP 带来(部门 / 组),或在本地管理。users(账号主体) + user_identities(user_id, type, identifier, credential),type = phone / email / wechat。无论哪种方式登录,最终都解析到同一个 user。各方式的实现要点 + 真实门槛(这里最容易被低估):
① 邮箱登录
最经典的方式。把「用户视角 → 服务端链路」走一遍就懂了(其他方式"拿到身份后签发会话"的链路是共通的,这里讲透):
注册(第一次)
verify?token=xxx)。登录(之后每次)
bcrypt.compare(输入, 哈希) 比对(不是明文相等)→ ③ 对了 → 签发 access + refresh token(见第一篇)→ ④ 返回 token / 种 HttpOnly Cookie。Magic Link(无密码版,体验更好):用户只输邮箱 → 服务端发一次性登录链接 → 用户点 → 服务端验 token(一次性 + 限时)→ 直接签发会话。好处:用户不用记密码、服务端根本不存密码(没有密码泄露风险)。
⚠️ 安全点:登录失败别分"邮箱不存在 / 密码错",统一回"邮箱或密码错误"——否则攻击者能靠它枚举出哪些邮箱注册过。
发信这关的坑(自建必踩):
② 手机号登录
③ 扫码登录
待扫描 → 已扫描 → 已确认 / 过期。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)。
上面的库以 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 的风格。
核心认知先放这:
鉴权是"重要但不差异化"的基础设施,安全坑又深 —— 能用成熟方案,就别从零自己搓。 绝大多数小公司不会自建完整鉴权体系。
| 用第三方 / IDaaS | 自己搭(或开源自建) |
|---|---|
| 团队小、想快速上线 | 有特殊定制、数据要完全自控 |
| 要企业 SSO、社会化登录(含微信)一站式 | 规模大到第三方成本不划算 |
| 鉴权不是核心竞争力(多数业务) | 有专门的安全团队 |
| 不想维护安全(密码 / 防刷 / 合规) | 愿意承担长期安全维护成本 |
中间路线:用开源自建(Keycloak / Logto)——自己部署、数据自控,但不从零写代码。
注意事项:
做鉴权前,对着这份安全底线逐条检查:
凭证与密码
Token
接口防护
运维
| 你的场景 | 选这个 |
|---|---|
| 个人项目 / 博客要登录 | 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 |
一句话总结:先问"这个场景的标准方案是什么",再问"自己搭还是用现成的",最后对着避坑清单过一遍。 鉴权不需要你发明轮子,需要你选对轮子、装稳。
这是「补服务端短板」系列鉴权专题的第二篇。上一篇 《JWT、OAuth、Token 刷新 —— 鉴权入门》 讲机制;这篇讲场景选型与避坑。完整代码与系列都在我的 GitHub:Aimee1608/backend-notes。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。