機能:サインインと認証メール

GoogleGoogle Cloudなしで。

アプリを使う人は、「Googleで続行」またはメールでサインインできます。Google CloudプロジェクトもOAuthクライアントもキーも不要です。新規登録のメールはアプリの名前で送られ、ドメインの確認が済むと、送信元は自分のドメインになります。

ドキュメントを読むエージェントのセットアップ

エージェントが呼び出すツール

  • appAuthConfigure
  • appAuthStatus
  • appAuthEmailConnect
  • appAuthEmailStatus
claude · ~/franks-kitchen例

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サインインの仕組み

Googleとやり取りするのはTofu。 アプリはやり取りしなくて済みます。

Tofuの中継サービスはoauth.trytofu.aiにあり、Googleクライアントと固定のコールバックアドレスを1⁠つずつ持っています。あなたのアプリはブラウザをそこへ送るだけです。あとは中継サービスが、ユーザーをアプリ自身の認証サービスにサインインさせます。認証サービスは、アプリのマネージドデータベースの裏側で動くSupabaseプロジェクトです。

新規登録メール

新規登録メールの差出人。あなたのアプリの名前です。

メールサインインも同じ1⁠回の設定で有効になります。Googleなどの外部サービスでのサインインがいつ使えなくなっても、アカウントに入り直す手段は必ず残ります。

アプリ自身の認証サービスは、Tofuが用意したメール送信の仕組みを通して、メール(confirmation、magic-link、password-reset、invitation、address-change、reauthentication)を送ります。差出人にはアプリの名前が表示されます。SMTPパスワードも、契約や登録が必要なメール配信サービスもありません。

どのメールにも、リンクに加えて1⁠回だけ使えるコードが入っています。メールのセキュリティスキャン(ウイルス対策など)がリンクを先に開いて、ユーザーが使う前にトークンを消費してしまうからです。

自分のドメインから送信

DNSレコードは6⁠件。 ドメインそのものには1⁠件もありません。

ドメインを接続すると、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 10bounce.sendfeedback-smtp.‹region›.amazonses.com
TXTbounce.sendv=spf1 include:amazonses.com ~all
TXT_dmarc.sendv=DMARC1; p=none; rua=mailto:…

ドメインを接続したときにCloudflareで承認済みなら、Tofuがレコードを書き込みます。2⁠度目の承認は不要です。承認がない場合は、追加するレコードを一覧で示し、メール配信サービスにドメインの確認を依頼します。

メール配信サービスがドメインを確認済みと報告するまで、メールはnotify.trytofu.appから送られ続けます。待っている間も、新規登録は止まりません。

アプリ自身が持つ唯一のルート

メールスキャナーが開いても、リンクは無効になりません。

メールのリンクはどれも、アプリ自身のアドレスにある/auth/confirmを指します。トークンが消費されるのは、アプリがverifyOtpを呼び出したときだけです。そのため、リンクを先に開いたスキャナーがたどり着くのは、認証サービスではなく、あなたのアプリです。

/tofuスキルで新しく作ったアプリには、エージェントがこのルートを書き込みます。このルートなしでデプロイされたアプリでも、ユーザーは各メールに書かれたコードでサインインできます。

app/auth/confirm/route.tsnext.js
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`);
}

近日対応

  • 同意画面に出るのはTofuの名前です。 Googleは、サインインに使うTofuのクライアントについて、確認済みのアプリ名を表示します。そのため、ユーザーには「Tofuに続行」と表示されます。そこに自分のアプリ名を出すには、自分のGoogleクライアントが必要です。この仕組みはまだありません。

  • Tofuのマネージドデータベースでのみ使えます。 Tofuは、アプリのマネージドデータベースが持つ認証サービスに、サインインの設定を書き込みます。Clerk、Auth0、自分のSupabaseプロジェクトを使っているアプリには、何も変更を加えません。

  • Googleとメールだけです。 アプリのユーザーは、GitHubやAppleでサインインできません。

  • 認証メールだけ。アプリのほかのメールは送りません。 Tofuが送るのは、サインインと新規登録のメールです。領収書や通知など、アプリが送るほかのメールはTofuを通りません。

  • 自分の送信元を使うには、自分のドメインが必要です。 先にドメインをアプリに接続する必要があります。ドメインの認証が済むまでは、メールはnoreply@notify.trytofu.appから届きます。

  • 自分のドメインからの送信は、いちばん新しい部分です。 Tofu自身のテストプロジェクトでは、DNSレコードの追加からドメインの認証、送信元の切り替えまで、一通り動作を確認済みです。ほかの人のアプリでは、まだ確認していません。

プロンプトを1⁠つ貼る。10⁠分でオンライン。

アプリも、データベースも、ドメインも、サインインも。いつものエージェントを使えば、約10⁠分でそろいます。

無料で始める