jpskill.com
💬 コミュニケーション コミュニティ

email-and-password-best-practices

Better Authのメール/パスワード認証機能で、メール認証設定、パスワード再設定フロー構築、パスワードポリシー設定、ハッシュ化アルゴリズムカスタマイズを行い、ログイン、サインイン、サインアップ時の認証やパスワードセキュリティを向上させるSkill。

📜 元の英語説明(参考)

Configure email verification, implement password reset flows, set password policies, and customise hashing algorithms for Better Auth email/password authentication. Use when users need to set up login, sign-in, sign-up, credential authentication, or password security with Better Auth.

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

一言でいうと

Better Authのメール/パスワード認証機能で、メール認証設定、パスワード再設定フロー構築、パスワードポリシー設定、ハッシュ化アルゴリズムカスタマイズを行い、ログイン、サインイン、サインアップ時の認証やパスワードセキュリティを向上させるSkill。

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

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

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

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

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

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して email-and-password-best-practices.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → email-and-password-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-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

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

クイックスタート

  1. メール/パスワードを有効にする: emailAndPassword: { enabled: true }
  2. emailVerification.sendVerificationEmail を設定する
  3. パスワードリセットフローのために sendResetPassword を追加する
  4. npx @better-auth/cli@latest migrate を実行する
  5. 検証: サインアップを試み、検証メールのトリガーを確認する

メール検証の設定

ユーザーのメールアドレスを検証するために、emailVerification.sendVerificationEmail を設定します。

import { betterAuth } from "better-auth";
import { sendEmail } from "./email"; // あなたのメール送信関数

export const auth = betterAuth({
  emailVerification: {
    sendVerificationEmail: async ({ user, url, token }, request) => {
      await sendEmail({
        to: user.email,
        subject: "メールアドレスの確認",
        text: `以下のリンクをクリックしてメールアドレスを確認してください: ${url}`,
      });
    },
  },
});

Note: url パラメータには完全な検証リンクが含まれています。カスタム検証 URL を構築する必要がある場合は、token が利用可能です。

メール検証の必須化

より厳格なセキュリティのために、emailAndPassword.requireEmailVerification を有効にして、ユーザーがメールを検証するまでサインインをブロックします。有効にすると、未検証のユーザーはサインインを試みるたびに新しい検証メールを受信します。

export const auth = betterAuth({
  emailAndPassword: {
    requireEmailVerification: true,
  },
});

Note: これには sendVerificationEmail の設定が必要であり、メール/パスワードでのサインインにのみ適用されます。

クライアントサイドの検証

即時のユーザーフィードバックとサーバー負荷の軽減のために、クライアントサイドの検証を実装します。

コールバック URL

サインアップおよびサインインリクエストでは、常に絶対 URL (オリジンを含む) をコールバック URL に使用してください。これにより、Better Auth がオリジンを推測する必要がなくなり、バックエンドとフロントエンドが異なるドメインにある場合に発生する可能性のある問題を回避できます。

const { data, error } = await authClient.signUp.email({
  callbackURL: "https://example.com/callback", // オリジンを含む絶対 URL
});

パスワードリセットフロー

パスワードリセットを有効にするには、メールとパスワードの設定で sendResetPassword を提供します。

import { betterAuth } from "better-auth";
import { sendEmail } from "./email"; // あなたのメール送信関数

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    // パスワードリセットメールを送信するためのカスタムメール送信関数
    sendResetPassword: async ({ user, url, token }, request) => {
      void sendEmail({
        to: user.email,
        subject: "パスワードのリセット",
        text: `以下のリンクをクリックしてパスワードをリセットしてください: ${url}`,
      });
    },
    // オプションのイベントフック
    onPasswordReset: async ({ user }, request) => {
      // ここにあなたのロジックを記述します
      console.log(`ユーザー ${user.email} のパスワードがリセットされました。`);
    },
  },
});

セキュリティに関する考慮事項

組み込みの保護機能: バックグラウンドでのメール送信 (タイミング攻撃の防止)、無効なリクエストに対するダミー操作、ユーザーの存在に関係なく一定の応答メッセージ。

サーバーレスプラットフォームでは、バックグラウンドタスクハンドラーを設定します。

export const auth = betterAuth({
  advanced: {
    backgroundTasks: {
      handler: (promise) => {
        // waitUntil のようなプラットフォーム固有のメソッドを使用します
        waitUntil(promise);
      },
    },
  },
});

トークンのセキュリティ

トークンはデフォルトで 1 時間後に失効します。resetPasswordTokenExpiresIn (秒単位) で設定します。

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    resetPasswordTokenExpiresIn: 60 * 30, // 30 分
  },
});

トークンはシングルユースであり、リセットが成功するとすぐに削除されます。

セッションの失効

パスワードリセット時に既存のすべてのセッションを無効にするには、revokeSessionsOnPasswordReset を有効にします。

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    revokeSessionsOnPasswordReset: true,
  },
});

パスワードの要件

パスワードの長さ制限 (設定可能):

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    minPasswordLength: 12,
    maxPasswordLength: 256,
  },
});

パスワードリセットの送信

リセットリンクを送信するには、requestPasswordReset を呼び出します。設定から sendResetPassword 関数をトリガーします。

const data = await auth.api.requestPasswordReset({
  body: {
    email: "john.doe@example.com", // 必須
    redirectTo: "https://example.com/reset-password",
  },
});

または authClient:

const { data, error } = await authClient.requestPasswordReset({
  email: "john.doe@example.com", // 必須
  redirectTo: "https://example.com/reset-password",
});

Note: email は必須ですが、よりスムーズなユーザーエクスペリエンスのために redirectTo を設定することもお勧めします。

パスワードハッシュ

デフォルト: scrypt (Node.js ネイティブ、外部依存関係なし)。

カスタムハッシュアルゴリズム

Argon2id または別のアルゴリズムを使用するには、カスタムの hash および verify 関数を提供します。

import { betterAuth } from "better-auth";
import { hash, verify, type Options } from "@node-rs/argon2";

const argon2Options: Options = {
  memoryCost: 65536, // 64 MiB
  timeCost: 3, // 3 iterations
  parallelism: 4, // 4 parallel lanes
  outputLen: 32, // 32 byte output
  algorithm: 2, // Argon2id variant
};

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    password: {
      hash: (password) => hash(password, argon2Options),
      verify: ({ password, hash: storedHash }) =>
        verify(storedHash, password, argon2Options),
    },
  },
});

Note: 既存のシステムでハッシュアルゴリズムを切り替えると、古いアルゴリズムを使用してハッシュされたパスワードを持つユーザーはサインインできなくなります。必要に応じて、移行戦略を計画してください。

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

Quick Start

  1. Enable email/password: emailAndPassword: { enabled: true }
  2. Configure emailVerification.sendVerificationEmail
  3. Add sendResetPassword for password reset flows
  4. Run npx @better-auth/cli@latest migrate
  5. Verify: attempt sign-up and confirm verification email triggers

Email Verification Setup

Configure emailVerification.sendVerificationEmail to verify user email addresses.

import { betterAuth } from "better-auth";
import { sendEmail } from "./email"; // your email sending function

export const auth = betterAuth({
  emailVerification: {
    sendVerificationEmail: async ({ user, url, token }, request) => {
      await sendEmail({
        to: user.email,
        subject: "Verify your email address",
        text: `Click the link to verify your email: ${url}`,
      });
    },
  },
});

Note: The url parameter contains the full verification link. The token is available if you need to build a custom verification URL.

Requiring Email Verification

For stricter security, enable emailAndPassword.requireEmailVerification to block sign-in until the user verifies their email. When enabled, unverified users will receive a new verification email on each sign-in attempt.

export const auth = betterAuth({
  emailAndPassword: {
    requireEmailVerification: true,
  },
});

Note: This requires sendVerificationEmail to be configured and only applies to email/password sign-ins.

Client Side Validation

Implement client-side validation for immediate user feedback and reduced server load.

Callback URLs

Always use absolute URLs (including the origin) for callback URLs in sign-up and sign-in requests. This prevents Better Auth from needing to infer the origin, which can cause issues when your backend and frontend are on different domains.

const { data, error } = await authClient.signUp.email({
  callbackURL: "https://example.com/callback", // absolute URL with origin
});

Password Reset Flows

Provide sendResetPassword in the email and password config to enable password resets.

import { betterAuth } from "better-auth";
import { sendEmail } from "./email"; // your email sending function

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    // Custom email sending function to send reset-password email
    sendResetPassword: async ({ user, url, token }, request) => {
      void sendEmail({
        to: user.email,
        subject: "Reset your password",
        text: `Click the link to reset your password: ${url}`,
      });
    },
    // Optional event hook
    onPasswordReset: async ({ user }, request) => {
      // your logic here
      console.log(`Password for user ${user.email} has been reset.`);
    },
  },
});

Security Considerations

Built-in protections: background email sending (timing attack prevention), dummy operations on invalid requests, constant response messages regardless of user existence.

On serverless platforms, configure a background task handler:

export const auth = betterAuth({
  advanced: {
    backgroundTasks: {
      handler: (promise) => {
        // Use platform-specific methods like waitUntil
        waitUntil(promise);
      },
    },
  },
});

Token Security

Tokens expire after 1 hour by default. Configure with resetPasswordTokenExpiresIn (in seconds):

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    resetPasswordTokenExpiresIn: 60 * 30, // 30 minutes
  },
});

Tokens are single-use — deleted immediately after successful reset.

Session Revocation

Enable revokeSessionsOnPasswordReset to invalidate all existing sessions on password reset:

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    revokeSessionsOnPasswordReset: true,
  },
});

Password Requirements

Password length limits (configurable):

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    minPasswordLength: 12,
    maxPasswordLength: 256,
  },
});

Sending the Password Reset

Call requestPasswordReset to send the reset link. Triggers the sendResetPassword function from your config.

const data = await auth.api.requestPasswordReset({
  body: {
    email: "john.doe@example.com", // required
    redirectTo: "https://example.com/reset-password",
  },
});

Or authClient:

const { data, error } = await authClient.requestPasswordReset({
  email: "john.doe@example.com", // required
  redirectTo: "https://example.com/reset-password",
});

Note: While the email is required, we also recommend configuring the redirectTo for a smoother user experience.

Password Hashing

Default: scrypt (Node.js native, no external dependencies).

Custom Hashing Algorithm

To use Argon2id or another algorithm, provide custom hash and verify functions:

import { betterAuth } from "better-auth";
import { hash, verify, type Options } from "@node-rs/argon2";

const argon2Options: Options = {
  memoryCost: 65536, // 64 MiB
  timeCost: 3, // 3 iterations
  parallelism: 4, // 4 parallel lanes
  outputLen: 32, // 32 byte output
  algorithm: 2, // Argon2id variant
};

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    password: {
      hash: (password) => hash(password, argon2Options),
      verify: ({ password, hash: storedHash }) =>
        verify(storedHash, password, argon2Options),
    },
  },
});

Note: If you switch hashing algorithms on an existing system, users with passwords hashed using the old algorithm won't be able to sign in. Plan a migration strategy if needed.