mcpField
A
api-auth-better-auth-drizzle-hono

api-auth-better-auth-drizzle-hono

github.com/agents-incセキュリティ2678 回インストール2 日前に更新
リポジトリ

api-auth-better-auth-drizzle-hono について

Better Authを使うTypeScript開発者向けの認証スキルです。設定、セッション、プラグイン、データベースマイグレーションを扱い、メールとパスワード、OAuth、二要素認証、組織単位のマルチテナントに対応します。

主な機能

  1. 01サーバー設定とデータベースアダプター
  2. 02型安全なセッションミドルウェア
  3. 03メール・パスワード認証フロー
  4. 04OAuthと二要素認証
  5. 05組織マルチテナント
  6. 06データベース、Cookieキャッシュ、ステートレスセッション

活用シーン

  1. 01TypeScriptアプリへのセルフホスト認証の追加
  2. 02型安全なセッションによるルート保護
  3. 03OAuthと二要素認証ログインの設定
  4. 04セッション方式の選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/agents-inc/skills --skill api-auth-better-auth-drizzle-hono

インストール後、Claude Code で/api-auth-better-auth-drizzle-honoを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

metadata.yaml
reference.md
examples/
core.md
oauth.md
organizations.md
sessions.md
two-factor.md

詳細

Better Auth による認証

クイックガイド: TypeScript アプリで、型安全かつセルフホスト可能な認証を実現するには Better Auth(v1.5 以降)を使用します。メール/パスワード、OAuth、2FA、セッション、ステートレス認証、組織のマルチテナンシーを提供します。プラグインアーキテクチャにより、段階的に複雑さを高められます。セッションに依存するミドルウェアより前に認証ハンドラーをマウントし、オリジンをまたぐデプロイでは先に CORS を設定します。また、プラグインを追加した後は必ずスキーマを生成します。


<critical_requirements>

重要:このスキルを使用する前に

(セッションに依存する他のミドルウェアより前に、認証ルートへ Better Auth ハンドラーをマウントする必要があります)

(クライアントとサーバーのオリジンが異なる場合、認証ルートより前に CORS ミドルウェアを設定する必要があります)

(すべてのシークレット(clientId、clientSecret、BETTER_AUTH_SECRET)に環境変数を使用する必要があります。ハードコードは絶対にしないでください)

(プラグインを追加した後は、npx auth@latest generate を実行し、続けて ORM のマイグレーションツールを実行する必要があります)

(ミドルウェアで型安全にセッションへアクセスするには、auth.$Infer.Session 型を使用する必要があります)

</critical_requirements>


自動検出: Better Auth、betterAuth、createAuthClient、auth.handler、auth.api.getSession、socialProviders、twoFactor プラグイン、organization プラグイン、drizzleAdapter、セッション管理、OAuth プロバイダー、ステートレスセッション、cookieCache、genericOAuth、oAuthProvider、passkey、SCIM

使用する場面:

  • セルフホスト可能な認証を構築する場合(ベンダーロックインなし)
  • メール/パスワード、OAuth、2FA を一つのソリューションで利用する場合
  • 組織/チーム管理を備えたマルチテナント SaaS の場合
  • 型安全なセッション管理が必要な場合
  • データベースに保存するセッション、またはステートレスセッションが必要なプロジェクトの場合

使用しない場面:

  • メンテナンス不要のマネージド認証が必要な場合(ホスト型認証ソリューションを検討してください)
  • ユーザーアカウントのないシンプルな静的サイトの場合
  • サーバーレスのコールドスタートが重大な問題となるプロジェクトの場合(ただし、ステートレスモードで改善できます)

対象となる主なパターン:

  • プラグインを使用したサーバー設定(auth.ts)
  • セッションミドルウェアと型安全なルート保護
  • メール/パスワード認証フロー
  • OAuth プロバイダー(GitHub、Google、汎用 OAuth)
  • 二要素認証(TOTP)
  • 組織とマルチテナンシー
  • セッション方式:データベース、Cookie キャッシュ、ステートレス
  • データベースアダプターとの統合
  • クライアント側の useSession フック
  • パフォーマンス:実験的な JOIN、Cookie キャッシュ、ステートレスセッション

詳細なリソース:


基本方針

Better Auth は、TypeScript を第一に考え、セルフホスト可能な認証アプローチを採用しています。ベンダーロックインなしで、ユーザーデータを自分のデータベースに保持できます。プラグインアーキテクチャにより、まずはシンプルに始め、必要に応じて機能を追加して段階的に複雑さを高められます。

基本原則:

  1. 一貫した型安全性 - auth.$Infer.Session を介して、セッション型がサーバーからクライアントへ引き継がれます
  2. データベースを信頼できる唯一の情報源とする - セッションは自分の DB に保存されます(オプションでステートレスモードも利用できます)
  3. プラグインベースの拡張性 - 必要に応じて 2FA、組織、パスキー、SCIM、OAuth プロバイダーを追加できます
  4. フレームワークに依存しない - どの TypeScript Web フレームワークでも動作します
  5. パフォーマンス重視 - 実験的な JOIN(2~3 倍高速)、Cookie キャッシュ、ステートレスセッション

基本パターン

パターン 1:サーバー設定(auth.ts)

データベースアダプターを使って auth インスタンスを作成します。すべての認証設定の信頼できる唯一の情報源です。

// lib/auth.ts
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/lib/db";

const SESSION_EXPIRES_IN_SECONDS = 60 * 60 * 24 * 7; // 7 days
const SESSION_UPDATE_AGE_SECONDS = 60 * 60 * 24; // Refresh daily

export const auth = betterAuth({
  database: drizzleAdapter(db, { provider: "pg" }),
  emailAndPassword: {
    enabled: true,
    minPasswordLength: 8,
    maxPasswordLength: 128,
  },
  session: {
    expiresIn: SESSION_EXPIRES_IN_SECONDS,
    updateAge: SESSION_UPDATE_AGE_SECONDS,
  },
  trustedOrigins: [process.env.APP_URL || "http://localhost:3000"],
});

良い理由: 名前付き定数によりセッションポリシーを監査でき、URL には環境変数を使用し、エクスポートするインスタンスを一つにしています。

// BAD: Magic numbers, hardcoded secrets, default export
const auth = betterAuth({
  database: { url: "postgres://user:pass@localhost/db" },
  session: { expiresIn: 604800 },
});
export default auth;

悪い理由: 認証情報をハードコードするとソース管理に漏えいし、マジックナンバーによってポリシーが分かりにくくなり、デフォルトエクスポートを使用しています。

メール認証と Drizzle アダプターの設定を含む完全なセットアップについては、examples/core.md を参照してください。


パターン 2:型安全なセッションミドルウェア

認証ハンドラーをマウントし、ルートでセッションにアクセスするための型付きミドルウェアを作成します。

// CRITICAL: CORS must be configured BEFORE auth routes
app.use("/auth/*", cors({ origin: APP_URL, credentials: true }));
app.on(["POST", "GET"], "/auth/*", (c) => auth.handler(c.req.raw));
// middleware/auth-middleware.ts - Type-safe session access
type AuthVariables = {
  user: typeof auth.$Infer.Session.user | null;
  session: typeof auth.$Infer.Session.session | null;
};

export const authMiddleware = createMiddleware<{ Variables: AuthVariables }>(
  async (c, next) => {
    const session = await auth.api.getSession({ headers: c.req.raw.headers });
    c.set("user", session?.user ?? null);
    c.set("session", session?.session ?? null);
    await next();
  },
);

良い理由: auth.$Infer.Session により c.get("user") に正しい型が適用され、認証より前に CORS を設定することでプリフライトの失敗を防ぎ、c.req.raw により Better Auth が必要とする Web 標準の Request を渡せます。

// BAD: No type annotation - c.user is any, bypasses type system
app.use("*", async (c, next) => {
  const session = await auth.api.getSession({ headers: c.req.raw.headers });
  c.user = session?.user; // any - no autocomplete
  await next();
});

悪い理由: AuthVariables 型がないとアクセスがすべて any になり、プロパティを直接代入すると型付き Variables を迂回します。

保護されたルートのパターンについては、examples/core.md を参照してください。


パターン 3:プラグイン追加後のスキーマ生成

各プラグインはデータベーステーブルを追加します。プラグインの追加または変更後に CLI を実行してください。

# Step 1: Generate Better Auth schema (outputs ORM-specific files)
npx auth@latest generate

# Step 2: Generate migration with your ORM tool
npx drizzle-kit generate

# Step 3: Apply migration
npx drizzle-kit migrate

必ず 3 つの手順をすべて実行してください。Better Auth の migrate コマンドは Kysely アダプターでのみ動作します。Drizzle では generate と Drizzle Kit を使用してください。


パターン 4:メール/パスワード認証と認証確認

認証確認とパスワードリセットのコールバックを含めて、メール/パスワード認証を設定します。

export const auth = betterAuth({
  database: drizzleAdapter(db, { provider: "pg" }),
  emailAndPassword: {
    enabled: true,
    minPasswordLength: 8,
    maxPasswordLength: 128,
    requireEmailVerification: true,
    sendResetPassword: async ({ user, url }) => {
      await sendEmail({
        to: user.email,
        subject: "Reset password",
        html: `<a href="${url}">Reset</a>`,
      });
    },
  },
  emailVerification: {
    sendVerificationEmail: async ({ user, url }) => {
      await sendEmail({
        to: user.email,
        subject: "Verify email",
        html: `<a href="${url}">Verify</a>`,
      });
    },
  },
});

良い理由: メール認証で偽のサインアップを防ぎ、パスワード要件をサーバー側で適用します。

エラー処理を含むクライアント側のサインアップ/サインインフックについては、examples/core.md を参照してください。


パターン 5:セッション戦略

トレードオフの異なる 3 つのセッション方式があります。

戦略DB が必要取り消し可能最適な用途
データベース(デフォルト)はいはいほとんどのアプリ
Cookie キャッシュ+DBはいはい(遅延あり)DB 負荷の軽減
ステートレスいいえいいえ(バージョンのみ)エッジ/サーバーレス
// Cookie cache: reduces DB hits by caching session in signed cookie
session: {
  cookieCache: { enabled: true, maxAge: CACHE_SECONDS, strategy: "compact" },
}

// Stateless: omit database option entirely
const auth = betterAuth({
  // No database = fully stateless
  session: { cookieCache: { enabled: true, strategy: "jwe" } },
});

Cookie キャッシュ戦略:compact(最小、内部用)、jwt(標準、サードパーティで検証可能)、jwe(暗号化され、データを秘匿)。

完全な設定と取り消しパターンについては、examples/sessions.md を参照してください。


<red_flags>

注意事項

  • シークレットのハードコード(ソース内の clientId/clientSecret)—環境変数を使用する必要があります
  • 認証ルートの後に CORS を設定—プリフライトリクエストが失敗します
  • BETTER_AUTH_SECRET 環境変数の設定漏れ—セッションが機能しません
  • プラグイン追加後のスキーマ生成漏れ—実行時にデータベースエラーが発生します
  • 型指定のないセッションミドルウェア—TypeScript の型安全性が失われ、c.user が any になります
  • Drizzle アダプターで auth.migrate() を使用—Kysely でのみ動作するため、generate と Drizzle Kit を使用してください
  • auth.handler() の呼び出し時に c.req.raw がない—生の Web 標準 Request を渡す必要があります

注意点とエッジケース:

  • Google がリフレッシュトークンを発行するのは初回の同意時のみです—accessType: "offline" と prompt: "consent" を使用してください
  • GitHub OAuth アプリはリフレッシュトークンを発行しません(アクセストークンの有効期間は長いです)
  • ステートレスセッションは個別に取り消せません。すべてを無効化するには version をインクリメントしてください
  • Cookie キャッシュの取り消しは、他のデバイスで maxAge が切れるまで遅延します
  • クロスドメインのデプロイでは、セッション Cookie に SameSite=None と Secure が必要です
  • authClient.forgotPassword は v1.4 で authClient.requestPasswordReset に改名されました
  • InferUser/InferSession は v1.5 で削除されました。better-auth の汎用 User と Session 型を使用してください

アンチパターンのコード例、判断フレームワーク、バージョンに関する注意事項については、reference.md を参照してください。

</red_flags>


<critical_reminders>

重要な注意事項

(セッションに依存する他のミドルウェアより前に、必ず認証ルートに Better Auth ハンドラーをマウントしてください)

(クライアントとサーバーのオリジンが異なる場合、必ず認証ルートより前に CORS ミドルウェアを設定してください)

(すべてのシークレット(clientId、clientSecret、BETTER_AUTH_SECRET)には必ず環境変数を使用してください。ハードコードは絶対に避けてください)

(プラグインを追加した後は、必ず npx auth@latest generate を実行してから、ORM のマイグレーションツールを実行してください)

(ミドルウェアで型安全にセッションへアクセスするには、必ず auth.$Infer.Session 型を使用してください)

これらのルールに従わないと、認証の失敗、セキュリティ上の脆弱性、または実行時エラーが発生します。

</critical_reminders>

コメント