jpskill.com
🛠️ 開発・MCP コミュニティ 🔴 エンジニア向け 👤 エンジニア・AI開発者

🛠️ Better認証BestPractices

better-auth-best-practices

包括的なTypeScript製の認証フレームワーク「Better Auth」を

⏱ MCPサーバー実装 1日 → 2時間

📺 まず動画で見る(YouTube)

▶ 【衝撃】最強のAIエージェント「Claude Code」の最新機能・使い方・プログラミングをAIで効率化する超実践術を解説! ↗

※ jpskill.com 編集部が参考用に選んだ動画です。動画の内容と Skill の挙動は厳密には一致しないことがあります。

📜 元の英語説明(参考)

Skill for integrating Better Auth - the comprehensive TypeScript authentication framework.

🇯🇵 日本人クリエイター向け解説

一言でいうと

包括的なTypeScript製の認証フレームワーク「Better Auth」を

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o better-auth-best-practices.zip https://jpskill.com/download/4436.zip && unzip -o better-auth-best-practices.zip && rm better-auth-best-practices.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/4436.zip -OutFile "$d\better-auth-best-practices.zip"; Expand-Archive "$d\better-auth-best-practices.zip" -DestinationPath $d -Force; ri "$d\better-auth-best-practices.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して better-auth-best-practices.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → better-auth-best-practices フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-17
取得日時
2026-05-18
同梱ファイル
1

💬 こう話しかけるだけ — サンプルプロンプト

  • Better Auth Best Practices を使って、最小構成のサンプルコードを示して
  • Better Auth Best Practices の主な使い方と注意点を教えて
  • Better Auth Best Practices を既存プロジェクトに組み込む方法を教えて

これをClaude Code に貼るだけで、このSkillが自動発動します。

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Better Auth 統合ガイド

コード例と最新のAPIについては、常にbetter-auth.com/docsを参照してください。

Better Authは、TypeScriptファーストでフレームワークに依存しない認証フレームワークであり、メール/パスワード、OAuth、マジックリンク、パスキーなどをプラグイン経由でサポートしています。


クイックリファレンス

環境変数

  • BETTER_AUTH_SECRET - 暗号化シークレット(32文字以上)。生成方法: openssl rand -base64 32
  • BETTER_AUTH_URL - ベースURL(例: https://example.com

環境変数が設定されていない場合にのみ、設定でbaseURL/secretを定義してください。

ファイルの場所

CLIはauth.ts././lib./utils、または./srcの下で探します。カスタムパスには--configを使用してください。

CLIコマンド

  • npx @better-auth/cli@latest migrate - スキーマを適用(組み込みアダプター)
  • npx @better-auth/cli@latest generate - Prisma/Drizzle用のスキーマを生成
  • npx @better-auth/cli mcp --cursor - AIツールにMCPを追加

プラグインを追加/変更した後に再実行してください。


コア設定オプション

オプション 注意事項
appName オプションの表示名
baseURL BETTER_AUTH_URLが設定されていない場合のみ
basePath デフォルトは/api/auth。ルートの場合は/を設定。
secret BETTER_AUTH_SECRETが設定されていない場合のみ
database ほとんどの機能で必須。アダプターのドキュメントを参照。
secondaryStorage セッションとレートリミット用のRedis/KV
emailAndPassword アクティブ化するには{ enabled: true }
socialProviders { google: { clientId, clientSecret }, ... }
plugins プラグインの配列
trustedOrigins CSRFホワイトリスト

データベース

直接接続: pg.Poolmysql2プール、better-sqlite3、またはbun:sqliteインスタンスを渡します。

ORMアダプター: better-auth/adapters/drizzlebetter-auth/adapters/prismabetter-auth/adapters/mongodbからインポートします。

重要: Better Authは、基になるテーブル名ではなく、アダプターのモデル名を使用します。PrismaモデルがUserでテーブルusersにマッピングされている場合、"users"ではなくmodelName: "user"(Prisma参照)を使用してください。


セッション管理

ストレージの優先順位:

  1. secondaryStorageが定義されている場合 → セッションはそこへ(DBではない)
  2. session.storeSessionInDatabase: trueを設定すると、DBにも永続化
  3. データベースなし + cookieCache → 完全なステートレスモード

クッキーキャッシュ戦略:

  • compact (デフォルト) - Base64url + HMAC。最小。
  • jwt - 標準JWT。読み取り可能だが署名済み。
  • jwe - 暗号化済み。最大のセキュリティ。

主要オプション: session.expiresIn (デフォルト7日)、session.updateAge (更新間隔)、session.cookieCache.maxAgesession.cookieCache.version (すべてのセッションを無効にするために変更)。


ユーザーとアカウントの設定

ユーザー: user.modelNameuser.fields (カラムマッピング)、user.additionalFieldsuser.changeEmail.enabled (デフォルトで無効)、user.deleteUser.enabled (デフォルトで無効)。

アカウント: account.modelNameaccount.accountLinking.enabledaccount.storeAccountCookie (ステートレスOAuth用)。

登録に必須: emailnameフィールド。


メールフロー

  • emailVerification.sendVerificationEmail - 検証が機能するために定義必須
  • emailVerification.sendOnSignUp / sendOnSignIn - 自動送信トリガー
  • emailAndPassword.sendResetPassword - パスワードリセットメールハンドラー

セキュリティ

advanced内:

  • useSecureCookies - HTTPSクッキーを強制
  • disableCSRFCheck - ⚠️ セキュリティリスク
  • disableOriginCheck - ⚠️ セキュリティリスク
  • crossSubDomainCookies.enabled - サブドメイン間でクッキーを共有
  • ipAddress.ipAddressHeaders - プロキシ用のカスタムIPヘッダー
  • database.generateId - カスタムID生成、または"serial"/"uuid"/false

レート制限: rateLimit.enabledrateLimit.windowrateLimit.maxrateLimit.storage ("memory" | "database" | "secondary-storage")。


フック

エンドポイントフック: hooks.before / hooks.after - { matcher, handler }の配列。createAuthMiddlewareを使用します。ctx.pathctx.context.returned (after)、ctx.context.sessionにアクセスできます。

データベースフック: databaseHooks.user.create.before/aftersessionaccountについても同様です。デフォルト値の追加や作成後のアクションに役立ちます。

フックコンテキスト (ctx.context): sessionsecretauthCookiespassword.hash()/verify()adapterinternalAdaptergenerateId()tablesbaseURL


プラグイン

ツリーシェイキングのために専用パスからインポートします:

import { twoFactor } from "better-auth/plugins/two-factor"

from "better-auth/plugins"ではありません。

人気のあるプラグイン: twoFactororganizationpasskeymagicLinkemailOtpusernamephoneNumberadminapiKeybearerjwtmultiSessionssooauthProvideroidcProvideropenAPIgenericOAuth

クライアントプラグインはcreateAuthClient({ plugins: [...] })に配置します。


クライアント

以下からインポートします: better-auth/client (バニラ)、better-auth/reactbetter-auth/vuebetter-auth/sveltebetter-auth/solid

主要メソッド: signUp.email()signIn.email()signIn.social()signOut()useSession()getSession()revokeSession()revokeSessions()


型安全性

型を推論します: typeof auth.$Infer.Sessiontypeof auth.$Infer.Session.user

クライアントとサーバーが分離したプロジェクトの場合: createAuthClient<typeof auth>()


よくある落とし穴

  1. モデル名 vs テーブル名 - 設定ではDBテーブル名ではなくORMモデル名を使用します
  2. プラグインスキーマ - プラグインを追加した後にCLIを再実行してください
  3. セカンダリストレージ - セッションはデフォルトでそこへ保存され、DBではありません
  4. クッキーキャッシュ - カスタムセッションフィールドはキャッシュされず、常に再フェッチされます
  5. ステートレスモード - DBがない場合、セッションはクッキーのみに保存され、キャッシュの有効期限が切れるとログアウトします
  6. メール変更フロー - 最初に現在のメールアドレスに送信され、次に新しいメールアドレスに送信されます

リソース

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Better Auth Integration Guide

Always consult better-auth.com/docs for code examples and latest API.

Better Auth is a TypeScript-first, framework-agnostic auth framework supporting email/password, OAuth, magic links, passkeys, and more via plugins.


Quick Reference

Environment Variables

  • BETTER_AUTH_SECRET - Encryption secret (min 32 chars). Generate: openssl rand -base64 32
  • BETTER_AUTH_URL - Base URL (e.g., https://example.com)

Only define baseURL/secret in config if env vars are NOT set.

File Location

CLI looks for auth.ts in: ./, ./lib, ./utils, or under ./src. Use --config for custom path.

CLI Commands

  • npx @better-auth/cli@latest migrate - Apply schema (built-in adapter)
  • npx @better-auth/cli@latest generate - Generate schema for Prisma/Drizzle
  • npx @better-auth/cli mcp --cursor - Add MCP to AI tools

Re-run after adding/changing plugins.


Core Config Options

Option Notes
appName Optional display name
baseURL Only if BETTER_AUTH_URL not set
basePath Default /api/auth. Set / for root.
secret Only if BETTER_AUTH_SECRET not set
database Required for most features. See adapters docs.
secondaryStorage Redis/KV for sessions & rate limits
emailAndPassword { enabled: true } to activate
socialProviders { google: { clientId, clientSecret }, ... }
plugins Array of plugins
trustedOrigins CSRF whitelist

Database

Direct connections: Pass pg.Pool, mysql2 pool, better-sqlite3, or bun:sqlite instance.

ORM adapters: Import from better-auth/adapters/drizzle, better-auth/adapters/prisma, better-auth/adapters/mongodb.

Critical: Better Auth uses adapter model names, NOT underlying table names. If Prisma model is User mapping to table users, use modelName: "user" (Prisma reference), not "users".


Session Management

Storage priority:

  1. If secondaryStorage defined → sessions go there (not DB)
  2. Set session.storeSessionInDatabase: true to also persist to DB
  3. No database + cookieCache → fully stateless mode

Cookie cache strategies:

  • compact (default) - Base64url + HMAC. Smallest.
  • jwt - Standard JWT. Readable but signed.
  • jwe - Encrypted. Maximum security.

Key options: session.expiresIn (default 7 days), session.updateAge (refresh interval), session.cookieCache.maxAge, session.cookieCache.version (change to invalidate all sessions).


User & Account Config

User: user.modelName, user.fields (column mapping), user.additionalFields, user.changeEmail.enabled (disabled by default), user.deleteUser.enabled (disabled by default).

Account: account.modelName, account.accountLinking.enabled, account.storeAccountCookie (for stateless OAuth).

Required for registration: email and name fields.


Email Flows

  • emailVerification.sendVerificationEmail - Must be defined for verification to work
  • emailVerification.sendOnSignUp / sendOnSignIn - Auto-send triggers
  • emailAndPassword.sendResetPassword - Password reset email handler

Security

In advanced:

  • useSecureCookies - Force HTTPS cookies
  • disableCSRFCheck - ⚠️ Security risk
  • disableOriginCheck - ⚠️ Security risk
  • crossSubDomainCookies.enabled - Share cookies across subdomains
  • ipAddress.ipAddressHeaders - Custom IP headers for proxies
  • database.generateId - Custom ID generation or "serial"/"uuid"/false

Rate limiting: rateLimit.enabled, rateLimit.window, rateLimit.max, rateLimit.storage ("memory" | "database" | "secondary-storage").


Hooks

Endpoint hooks: hooks.before / hooks.after - Array of { matcher, handler }. Use createAuthMiddleware. Access ctx.path, ctx.context.returned (after), ctx.context.session.

Database hooks: databaseHooks.user.create.before/after, same for session, account. Useful for adding default values or post-creation actions.

Hook context (ctx.context): session, secret, authCookies, password.hash()/verify(), adapter, internalAdapter, generateId(), tables, baseURL.


Plugins

Import from dedicated paths for tree-shaking:

import { twoFactor } from "better-auth/plugins/two-factor"

NOT from "better-auth/plugins".

Popular plugins: twoFactor, organization, passkey, magicLink, emailOtp, username, phoneNumber, admin, apiKey, bearer, jwt, multiSession, sso, oauthProvider, oidcProvider, openAPI, genericOAuth.

Client plugins go in createAuthClient({ plugins: [...] }).


Client

Import from: better-auth/client (vanilla), better-auth/react, better-auth/vue, better-auth/svelte, better-auth/solid.

Key methods: signUp.email(), signIn.email(), signIn.social(), signOut(), useSession(), getSession(), revokeSession(), revokeSessions().


Type Safety

Infer types: typeof auth.$Infer.Session, typeof auth.$Infer.Session.user.

For separate client/server projects: createAuthClient<typeof auth>().


Common Gotchas

  1. Model vs table name - Config uses ORM model name, not DB table name
  2. Plugin schema - Re-run CLI after adding plugins
  3. Secondary storage - Sessions go there by default, not DB
  4. Cookie cache - Custom session fields NOT cached, always re-fetched
  5. Stateless mode - No DB = session in cookie only, logout on cache expiry
  6. Change email flow - Sends to current email first, then new email

Resources