功能 · 登录与邮件
Google登录,不用碰 Google Cloud
用户可以用 Google 或邮箱登录你的 app。你不用建 Google Cloud 项目,不用配 OAuth 客户端,也不用管密钥。注册邮件的发件人显示 app 的名字,等域名验证通过,就从你自己的域名发出。
Let staff sign in with Google
Update(app/login/page.tsx)
1 line · Google button → TOFU_SIGN_IN_URL
Write(app/auth/confirm/route.ts)
new route · verifyOtp for the email link
tofu · appAuthConfigure confirmed: true
configured · Google sign-in, and email sign-in as well
Google 登录的工作原理
Tofu 来和 Google 打交道, 你的 app 就不用了
Tofu 的中转服务 oauth.trytofu.ai 自带一个 Google OAuth 客户端和一个固定的回调地址。你的 app 让用户跳转到中转服务,中转服务再帮他们登录 app 自己的认证服务。这个认证服务,就是托管数据库背后的 Supabase 项目。
- 你的 app用户点“使用 Google 账号继续”,浏览器就跳到 Tofu 的中转服务。
- oauth.trytofu.ai只做一件事:检查登录后要跳回的地址是不是你 app 自己的。
- Google用户在 Google 的页面上登录,并同意授权给 Tofu。
- 你 app 的登录服务在这里新建账号或找到已有账号,用户回到你的 app 时就已经登录了。
只有中转服务直接和 Google 打交道,所以你不需要 Google Cloud 项目、OAuth 客户端或密钥。每做一个 app,也没人需要去 Google Cloud 控制台单独设置。
你确认一次,appAuthConfigure 就会把 Google 登录和邮箱登录一起写进你 app 的登录服务。写完还会把配置读回来核对,没问题才说已配置。
部署时带上数据库,并不会自动开启登录。登录要在部署完成后单独开启一次,重复开启也没关系。
// Continue with Google — Tofu brokers the sign-in.
window.location.href = process.env.NEXT_PUBLIC_TOFU_SIGN_IN_URL + "?return=" +
encodeURIComponent(window.location.href);&flow=pkce,还要加一个小路由来完成登录。这两处,你的 agent 都会写好。注册和登录邮件,用你 app 的名字发出
邮箱登录会和 Google 登录一起开启。这样就算哪天 Google 这类第三方登录用不了,用户也总能用邮箱登回自己的账号。
你 app 自己的登录服务会发这几类邮件(confirmation、magic-link、password-reset、invitation、address-change 和 reauthentication),用的是 Tofu 配好的发信设置,发件人显示为你 app 的名字。不用 SMTP 密码,也不用另外注册邮件服务商。
每封邮件除了链接,还附带一个一次性验证码。有些邮箱的安全扫描会抢先点开链接,把里面的 token 用掉,用户再点就晚了。
| 阶段 | 发件地址 |
|---|---|
| 域名验证通过前 | noreply@notify.trytofu.app |
| 域名验证通过后 | noreply@send.frankskitchen.com |
用你的域名发邮件
6 条 DNS 记录, 一条都不在你的主域名上
域名连好后,appAuthEmailConnect 会把 send.frankskitchen.com 设为发件域名,并添加对应的 DNS 记录。这些记录都在 send. 这个子域名下,完全不影响你域名原有的收信设置。删掉这些记录,域名就恢复原样。
| 类型 | 名称(不含 frankskitchen.com) | 值 |
|---|---|---|
| CNAME | ‹token 1›._domainkey.send | ‹token 1›.dkim.amazonses.com |
| CNAME | ‹token 2›._domainkey.send | ‹token 2›.dkim.amazonses.com |
| CNAME | ‹token 3›._domainkey.send | ‹token 3›.dkim.amazonses.com |
| MX 10 | bounce.send | feedback-smtp.‹region›.amazonses.com |
| TXT | bounce.send | v=spf1 include:amazonses.com ~all |
| TXT | _dmarc.send | v=DMARC1; p=none; rua=mailto:… |
如果连接域名时,你已经在 Cloudflare 上授权过 Tofu,这些记录会自动写好,不用再授权一次。其他情况下,Tofu 会列出要添加的记录,等你加好,再请邮件服务商验证。
域名在邮件服务商那里通过验证之前,邮件照常从 notify.trytofu.app 发出,用户注册和登录都不受影响。
邮件扫描器先点开,登录链接也不会失效
每封邮件里的链接都指向你的 app 自己的 /auth/confirm。只有 app 调用了 verifyOtp,token 才会用掉。所以邮件扫描器就算抢先点开,访问的也只是你的 app,碰不到登录服务,链接照样能用。
用 /tofu skill 新做的 app,你的 agent 会写好这条路由。如果 app 部署时没有这条路由,用户照样能输入邮件里的验证码登录。
import { createClient } from '@/lib/supabase/server';
import { NextResponse } from 'next/server';
export async function GET(request) {
const { searchParams, origin } = new URL(request.url);
const token_hash = searchParams.get('token_hash');
const type = searchParams.get('type');
if (token_hash && type) {
const supabase = await createClient();
const { error } =
await supabase.auth.verifyOtp({ type, token_hash });
if (!error) return NextResponse.redirect(`${origin}/`);
}
return NextResponse.redirect(`${origin}/login?error=link`);
}还没做到的,很快会补上
Google 授权页上显示的是 Tofu 的名字。 登录走的是 Tofu 的 Google 客户端,Google 会显示它经过验证的名字,所以用户看到的是“继续前往 Tofu”。要换成你自己的名字,得用你自己的 Google 客户端,这个功能还没做。
只能搭配 Tofu 托管数据库。 Tofu 会把登录设置写进托管数据库自带的登录服务。如果你的 app 用的是 Clerk、Auth0,或者你自己的 Supabase 项目,Tofu 不会做任何改动。
只支持 Google 和邮箱登录。 你的 app 用户不能用 GitHub 或 Apple 登录。
只管登录邮件,不管 app 的其他邮件。 Tofu 发登录和注册邮件。收据、通知和 app 发的其他邮件,都不经过 Tofu。
想用自己的发件地址,得有自己的域名。 域名要先连接到 app。域名验证通过之前,邮件还是从 noreply@notify.trytofu.app 发出。
用自己的域名发件,是最新加的功能。 添加 DNS 记录、验证域名、切换发件地址,这一整套流程已经在 Tofu 自己的测试项目上完整跑通,但还没在其他人的 app 上用过。
说说你想做什么 app,或者带上 agent 已经做好的 app。Tofu 帮你上线。
任何 coding agent 都能用
© 2026 Tofu
trytofu.ai
本页由英文翻译;如有内容冲突,请以英文原版为准。