Multica Docs

登录与注册配置

配 Email 验证码登录 + Google OAuth + 注册白名单。避开最坑的 888888 陷阱。

Multica 支持两种登录方式:Email + 验证码(默认)和 Google OAuth(可选)。登录成功后 server 签发一个 30 天有效期的 JWT cookie。这一页讲怎么配、怎么限制谁能注册、以及自部署最容易踩的一个陷阱。

上面用到的环境变量的清单见 环境变量;token 怎么用、生命周期细节见 认证与令牌

Email + 验证码登录怎么工作

用户在登录页输邮箱 → server 发 6 位验证码 → 用户填回 → server 验证 → 签发 JWT cookie。是标准流程。需要 Resend 作为邮件发送服务:

  1. 在 Resend 建账号、验证你的域名

  2. 创建 API key

  3. 设环境变量:

    RESEND_API_KEY=re_xxxxxxxxxxxxxxxx
    RESEND_FROM_EMAIL=noreply@yourdomain.com  # 必须是 Resend 已验证的域名
  4. 重启 server

不配 RESEND_API_KEY 的后果:server 不报错,但所有本该发出去的邮件只打到 server 的 stdout。本地开发方便(你从日志抄验证码),生产环境等于黑洞。

888888 陷阱

APP_ENV 不设为 production,任何人都能用验证码 888888 登录任何账号。

Multica 有一个开发用的主验证码(master code)888888——为了本地开发不依赖 Resend 而设的后门。判定逻辑很简单:APP_ENV != "production" 时,任何邮箱888888 都能通过。

生产部署必须设 APP_ENV=production。如果你用 make selfhost / docker-compose.selfhost.yml 自部署,这个值已经默认设为 production;但如果你自己从源码部署、自己写 Docker 配置、或者在 Kubernetes 里重新定义环境变量——一定要自己把 APP_ENV=production 加上。

检查你的部署是否有这个陷阱:打开登录页,输入任意邮箱请求验证码,再在验证码栏输 888888。如果能登进去 = 你的 APP_ENV 没设成 production整个实例处于完全开放状态

怎么配 Google OAuth

可选。不配就只有 Email + 验证码登录;配了后登录页会多出「用 Google 登录」按钮。

  1. Google Cloud Console 创建一个 OAuth 2.0 client

  2. 授权的回调 URI(Authorized redirect URIs)填你的 Multica 前端地址加 /auth/callback,例如:

    https://multica.yourdomain.com/auth/callback
  3. 拿到 client ID 和 client secret 后设三个环境变量:

    GOOGLE_CLIENT_ID=xxxxx.apps.googleusercontent.com
    GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxx
    GOOGLE_REDIRECT_URI=https://multica.yourdomain.com/auth/callback
  4. 重启 server。

热生效:前端通过 /api/config 运行时读这些配置——改完只要重启 server,前端不用重建镜像、不用重新部署。

回调 URI 在 Google Console 和 GOOGLE_REDIRECT_URI 两处必须完全一致,包括协议(http vs https)、尾部斜杠、端口。不一致 Google 会拒绝整个 OAuth 流程,用户看到的错误是 redirect_uri_mismatch

怎么限制谁能注册

三层环境变量按优先级组合:

Rendering diagram…

已经登录过的老用户永远可以再次登录——signup 白名单只对首次注册生效,不拦截老用户。

  • ALLOWED_EMAILS(最高优先级)—— 显式邮箱白名单,逗号分隔。非空时只有列表里的邮箱能注册
  • ALLOWED_EMAIL_DOMAINS—— 域名白名单,逗号分隔(例如 company.io,partner.com)。
  • ALLOW_SIGNUP —— 总开关,默认 true。设 false 完全关闭注册。

三层白名单是 AND 语义,不是 OR。 很多人第一直觉是「设 ALLOWED_EMAIL_DOMAINS=company.io + ALLOW_SIGNUP=true 就是允许 company.io 和其他所有人」——不是。任何一层白名单只要设了非空值,不匹配的邮箱直接拒ALLOW_SIGNUP=true 挡不住。

要真的「允许所有人」,所有三个环境变量都留空(或 ALLOW_SIGNUP=true)。

典型配法

需求配置
公司内网,只允许 company.io 员工ALLOWED_EMAIL_DOMAINS=company.io
公司内网 + 几个外部合作者ALLOWED_EMAIL_DOMAINS=company.io + 合作者个人邮箱加到 ALLOWED_EMAILS
完全关闭自助注册,只能邀请ALLOW_SIGNUP=false
开放注册(不推荐生产用)三个都留空

关了注册还能邀请人进来吗

只对已经有 Multica 账号的人能。接受邀请那一步不检查 signup 白名单——如果对方已经注册过(比如在别的工作区),他们点链接登录就能直接接受。

但还没注册过的人,邀请救不了他们。他们接受邀请前必须先登录,登录的第一步(发验证码)会过 signup 白名单检查。如果你 ALLOW_SIGNUP=false、或他们的邮箱不在 ALLOWED_EMAILS / ALLOWED_EMAIL_DOMAINS 里,他们没法完成注册,也就没法接受邀请。

要邀请一个还没注册的外部协作者:临时把他们的邮箱加到 ALLOWED_EMAILS,等他们注册 + 接受邀请之后再把这条移掉。

邀请的创建和使用见 成员与权限

下一步

  • 环境变量 —— 这一页用到的环境变量完整定义
  • 认证与令牌 —— JWT / PAT / Daemon Token 的分类和使用
  • 故障排查 —— 验证码收不到、OAuth 报 redirect_uri_mismatch、注册被拒的常见排查