필사 모드: API & ウェブアプリ認証ライブラリ 2026 完全ガイド - Auth.js v5 · Lucia v3 · better-auth · Clerk · Stytch · WorkOS · Kinde · SuperTokens · Frontegg 徹底分析
日本語プロローグ — 2026年、「認証は自前で作るべきか?」
2010年代は「ログイン画面くらい自前で作る」がデフォルトだった。2020年代前半は、Auth0 と Firebase Auth が登場し「認証は SaaS にアウトソースする」が主流になった。そして2026年、私たちは再び岐路に立っている。
- 一方には **Clerk、Stytch、WorkOS、Kinde、Frontegg** のようなマネージド SaaS が、パスキー、MFA、SSO、SCIM までを箱に詰めて月 $25 〜 $1000+ で売る。
- もう一方には **Auth.js v5**(旧 NextAuth)、**Lucia v3**(現在はメンテナンスモード)、**better-auth** のような OSS ライブラリが「あなたの DB、あなたのコード、あなたのドメイン」を訴える。
- その中間に **SuperTokens**、**Logto**、**Ory** のような「オープンソース SaaS」オプションがある。セルフホストもできるし、マネージドホスティングも受けられる。
この記事はその地形全体を見る。ライブラリ・SaaS オプションを一つずつ見て、OAuth フローとパスキーのようなプロトコル層を解きほぐし、B2B 要件(SSO/SCIM/監査ログ)を整理し、韓国・日本のローカル認証プロバイダまで扱う。最後に「誰が何を選ぶべきか」を提言する。
1. 2026年ウェブアプリ認証地形図 — Library vs Managed vs OSS-SaaS
大きく三つの陣営がある。
┌──────────────────────────────────────────────────────────────────────┐
│ 2026年ウェブアプリ認証の三カテゴリ │
│ │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────────┐ │
│ │ Library │ │ Managed SaaS │ │ OSS-SaaS / Hybrid │ │
│ │ (DIY) │ │ (Buy) │ │ (Self-host OK) │ │
│ │ │ │ │ │ │ │
│ │ - Auth.js v5 │ │ - Clerk │ │ - SuperTokens │ │
│ │ - Lucia v3 │ │ - Stytch │ │ - Logto │ │
│ │ - better-auth │ │ - WorkOS │ │ - Ory Network │ │
│ │ - iron-session │ │ - Kinde │ │ - Keycloak Cloud │ │
│ │ - Passport.js │ │ - Frontegg │ │ - Hanko Cloud │ │
│ │ - JOSE/jose │ │ - Auth0 │ │ │ │
│ └────────────────┘ └────────────────┘ └────────────────────┘ │
│ ↑ ↑ ↑ │
│ 自分の DB 相手の DB 両方可 │
│ 自分のドメイン 相手のウィジェット ほぼ両方 │
│ $0/MAU $25 〜 $2000+/M $0 〜 数百/M │
└──────────────────────────────────────────────────────────────────────┘
各陣営の強みと弱み。
| カテゴリ | 強み | 弱み | 向いているチーム |
| --- | --- | --- | --- |
| **Library** | フルコード制御、コスト 0、データ所有 | セキュリティ責任 100%、時間を食う、パスキー/SSO 自前実装 | シニアフルスタック 1〜2名、MAU 10万未満、コンプライアンス自己責任 |
| **Managed** | 出荷が速い、MFA/SSO/SCIM が箱の中、SOC2 を継承 | 費用がMAUで爆発、ロックイン、ドメイン依存 | シード〜シリーズ B スタートアップ、MAU 急増想定 |
| **OSS-SaaS** | セルフホスト可、コード可視性 | 運用が複雑、結局マネージドはマネージド費用 | エンタープライズ、データ主権、EU/韓国の規制業界 |
2026年の大きな流れ: **ハイブリッド移行**が増えている。「Clerk で始めて MAU 5万を超えたら better-auth に移る」がよくあるシナリオだ。移行が高くつくので、初期選択は依然として重要。
2. Auth.js v5(旧 NextAuth.js)— Node/Next.js の事実上の標準
**Auth.js v5** は NextAuth.js の後継。2024年の v5 メジャーリブランドで、Next.js 以外に SvelteKit、SolidStart、Express、Hono などへとアダプターを広げた。
コアモデル
- **Auth Core** + **フレームワークアダプター** + **DB アダプター** + **プロバイダ**の 4 層。
- DB アダプター: Prisma、Drizzle、Kysely、TypeORM、MongoDB、DynamoDB など。
- プロバイダ: Google、GitHub、Apple、Microsoft、NAVER、Kakao など 80+ OAuth プロバイダ + Email + Credentials。
- セッションのデフォルトは JWT クッキー。アダプターを付ければ DB セッションも可能。
// auth.ts (Next.js App Router)
export const { auth, handlers, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [Google],
session: { strategy: 'database' },
callbacks: {
async session({ session, user }) {
session.user.id = user.id
return session
},
},
})
v5 の変更点(v4 → v5)
- `getServerSession` → 単一の `auth()` ヘルパに統一。
- 環境変数を自動推論(AUTH_GOOGLE_ID など)。
- Edge ランタイム互換性の改善。
- `account.providerAccountId` ポリシーの変更 — 移行ガイド必読。
強み / 弱み
- 強み: 完全 OSS、無料、Next.js フレンドリー、巨大コミュニティ、80+ プロバイダ。
- 弱み: パスキーはまだベータアダプター、MFA/SCIM は内蔵なし(自前実装)、デバッグが難しい魔法がある。
- 一言: 「Next.js で、マネージドを使わないなら、出発点は Auth.js v5」
3. Lucia v3 → better-auth への流れ
**Lucia v3**(著者: pilcrowOnPaper)は、2023〜2024年に「フレームワーク非依存のミニマルなセッションライブラリ」として人気を博した。中核は `Lucia` オブジェクト + アダプター + 自分で書くルート。魔法がほとんど無く、セキュリティに敏感なチームに好まれた。
しかし2025年3月、著者は[Lucia のメンテナンスモード入り](https://github.com/lucia-auth/lucia)を宣言した。理由は「ライブラリよりも学習リソース(コピー&ペースト)として位置づける方がよい」。その席を素早く埋めたのが **better-auth**。
better-auth — TypeScript-first、プラグインアーキテクチャ
**better-auth**(著者: bekacru)は2024年に登場、2025年に爆発的に伸びた。設計は以下のとおり。
- TypeScript-first、型推論が完璧。
- プラグインアーキテクチャ — パスキー、OAuth、マジックリンク、2FA、組織(Organization)などすべてプラグイン。
- フレームワークアダプター — Next.js、SvelteKit、Nuxt、Hono、Express、Astro など。
- 自前のクライアント SDK — `useSession`、`signIn`、`signOut` がフレームワークごとに自動生成。
// auth.ts
export const auth = betterAuth({
database: prismaAdapter(prisma, { provider: 'postgresql' }),
emailAndPassword: { enabled: true },
socialProviders: {
google: { clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET! },
},
plugins: [passkey(), twoFactor(), organization()],
})
Auth.js vs better-auth
| 観点 | Auth.js v5 | better-auth |
| --- | --- | --- |
| リリース | 2018(NextAuth)〜 2024(v5) | 2024 |
| フレームワーク | Next.js 中心、複数対応 | Next.js、SvelteKit、Nuxt を同等にサポート |
| パスキー | ベータアダプター | 一級プラグイン |
| 2FA / MFA | 自前実装 | プラグイン |
| 組織 / マルチテナント | 自前実装 | プラグイン |
| 型推論 | OK | より強い |
| 成熟度 | 高い | 急速に追従中 |
2026年時点で新規 Next.js プロジェクトなら、better-auth を本気で検討する価値がある。Auth.js は安定性とエコシステム、better-auth は機能の豊かさと型安全性で分かれる。
4. Clerk — マネージド UX のゴールドスタンダード
**Clerk**(2021年創業、YC W21)は2024〜2026年で、マネージド認証 SaaS の事実上の標準になった。強みは明快だ。
- 箱の中の**美しい React UI コンポーネント** — `<SignIn />`、`<SignUp />`、`<UserButton />`。
- パスキー、MFA(TOTP/SMS/バックアップコード)、マジックリンク、OAuth 50+ プロバイダが箱の中。
- 組織(B2B)、権限、招待、永続セッション、デバイス管理、アクティブセッション表示。
- Next.js、React、Remix、Expo などの SDK が豊富。
価格(2026年第1四半期時点)
- Free: MAU 10,000 まで、基本機能。
- Pro: $25/月 + MAU $0.02(10,000 MAU 超過分)。
- Business: $99/月から、SAML SSO 追加。
- Enterprise: 個別見積、SCIM、監査ログ、SOC2 Type II。
コードサンプル
// app/layout.tsx
export default function RootLayout({ children }) {
return (
)
}
// app/sign-in/page.tsx
export default function Page() {
return <SignIn />
}
Clerk の罠
- **MAU 価格の急増** — MAU 5万を超えると月 $1,000+ をあっさり越える。シード/プレシードは安全だが、シリーズ A 以降は請求書ショックがよくある。
- **ドメイン依存** — Clerk がホストするページ(`accounts.your-app.com`)に依存。100% 自分のドメインは Business 以上。
- **データ移行** — ユーザーデータは Clerk が保有。移行可能だがパスワードは取り戻せない。
5. Stytch — パスワードレス中心、B2C/B2B 分離
**Stytch**(2020年創業、シリーズ B 評価)はパスワードレス認証に最も早く集中投資した。
- マジックリンク、メール OTP、SMS OTP、WhatsApp OTP、パスキー、OAuth、TOTP。
- **B2C SDK**と**B2B SDK**が分離 — B2B には組織、SSO、SCIM、メンバー管理が内蔵。
- ヘッドレス SDK が強み — 自分の UI を作り、バックエンドは Stytch。
B2B SaaS シナリオでの強み
Stytch B2B は**組織単位**で認証が設計されている。
- 組織ごとに SSO(SAML/OIDC)を接続可能。
- 組織ごとに MFA ポリシー(必須/任意)。
- 組織ごとにロールと権限(Owner、Admin、Member、Stytch Resource ベースの RBAC)。
- ドメイン一致による自動加入(例: `user@acme.com` メールは Acme 組織に自動追加)。
const stytch = new StytchClient({
project_id: process.env.STYTCH_PROJECT_ID!,
secret: process.env.STYTCH_SECRET!,
})
// マジックリンク送信
await stytch.magicLinks.email.loginOrCreate({
email: 'user@acme.com',
login_magic_link_url: 'https://app.example.com/auth/callback',
})
価格
- Stytch Consumer Free: MAU 10,000 まで。
- Pro: MAU $0.05 + 機能別。
- Stytch B2B: 組織単位、通常 $99/組織/月 + 機能。
6. WorkOS — エンタープライズ SSO/SCIM に特化
**WorkOS** は「B2B SaaS がエンタープライズに上がるとき詰まる SSO/SCIM/監査ログを一箱で解く」がポジショニング。
- **SSO Connections**: SAML 2.0、OIDC、Google Workspace、Microsoft Entra、Okta、OneLogin、JumpCloud など 30+。
- **Directory Sync (SCIM)**: Okta、Microsoft Entra、JumpCloud、Rippling、BambooHR、Workday など 25+。
- **Audit Logs**、**Magic Link**、**MFA**、**Admin Portal**(顧客が直接 IdP を接続)。
- AuthKit — 無料のホスト型ログインページ(Clerk に近い)。
中核となる価格モデル
WorkOS の価格は他とは違う。
- **SSO**: $99 / 接続 / 月。10 接続目から割引。
- **SCIM(Directory Sync)**: $0.125 / ユーザー / 月。
- **Audit Logs**: $0.05 / イベント。
- **AuthKit**: 1M MAU まで無料。
つまり B2B のエンタープライズ顧客 1 件で SSO $99/月なら、それがそのまま売上。「エンタープライズ 1 件 = 平均 LTV 数万ドル」という SaaS 経済に合った価格設計。
コードサンプル — SSO フロー
const workos = new WorkOS(process.env.WORKOS_API_KEY!)
// 1) ログイン URL を生成
const authUrl = workos.sso.getAuthorizationUrl({
connection: 'conn_01EHWNCE74X7JSDV0X3SZ3KJNY',
redirectUri: 'https://app.example.com/callback',
clientId: process.env.WORKOS_CLIENT_ID!,
})
// 2) コールバックでプロフィール取得
const { profile, accessToken } = await workos.sso.getProfileAndToken({
code: searchParams.code,
clientId: process.env.WORKOS_CLIENT_ID!,
})
7. Kinde — フルスタックマネージド、「Auth0 より安くシンプル」
**Kinde**(2022年オーストラリア創業)は「Auth0 の複雑さと価格を減らす」が目標だった。結果、次のものを箱の中に。
- B2C ユーザー認証 + B2B 組織(テナント)。
- フィーチャーフラグ(独自フラグシステム搭載)。
- 課金(Stripe 連携)、権限、ロール。
- ホスト型ログインページまたは自前 UI。
価格
- Free: MAU 10,500 まで。
- Plus: $25/月 + MAU。
- Scale、Enterprise は要見積。
特徴: **Free プランが最も寛大**。MAU 10,500 無料は2026年時点で最も大盤振る舞いだ。
8. SuperTokens — オープンソース SaaS、セルフホスト可
**SuperTokens**(2020年創業、YC W21)はオープンソース + マネージドのデュアルモデル。
- コードはすべてオープンソース。Apache 2.0。
- Core サービス(SuperTokens Core)+ バックエンド SDK + フロント SDK の分離。
- SaaS でホスト、または自前インフラ(Docker、Kubernetes)で起動可能。
- パスワードレス、パスキー、OAuth、セッション、MFA、マルチテナント。
価格
- Self-hosted: $0。自前インフラ。
- Managed Core: MAU 5,000 まで無料、以降 $0.02/MAU。
コードサンプル
SuperTokens.init({
framework: 'express',
supertokens: {
connectionURI: 'http://localhost:3567', // または managed core URL
},
appInfo: {
appName: 'My App',
apiDomain: 'https://api.example.com',
websiteDomain: 'https://example.com',
},
recipeList: [
ThirdPartyEmailPassword.init({ /* providers */ }),
Session.init(),
],
})
SuperTokens の一言: 「OSS 忠誠は高いが、マネージドも欲しいとき」
9. Frontegg — B2B マネージド顧客認証
**Frontegg**(2019年イスラエル創業)は B2B SaaS の顧客認証をフルスタックで解く、というポジショニング。
- 組織(テナント)、ユーザー、ロール、権限、SSO、SCIM、監査ログ、通知。
- ホスト型ログインボックス + 管理者ポータル。
- 価格は見積ベース — 通常シード/シリーズ A には高い。
WorkOS とポジショニングは重なるが違いがある。
- **WorkOS**: B2B の SSO/SCIM インフラレイヤー。自前の認証システムと組み合わせる。
- **Frontegg**: B2B 認証の丸ごとの箱。自前の認証システムをほとんど作らない。
10. Hanko — パスキー・ファーストの OSS
**Hanko** はドイツ発の OSS プロジェクトで、スローガンは「パスワードを殺せ」。パスキー、WebAuthn、パスコード(OTP)を中心に据えている。
- Go で書かれたバックエンドサービス + JS ウェブコンポーネント。
- マネージドの Hanko Cloud オプション + セルフホスト。
- `<hanko-auth />` ウェブコンポーネントが核 — どのフレームワークでも動く。
パスキーだけを素早く敷きたいなら Hanko が一番シンプル。ただし OAuth ソーシャルログインのカバレッジが他より薄い。
11. Passport.js / iron-session / jose — Node レガシー + ミニマル
3 つの古典。
- **Passport.js**(Jared Hanson、2011〜)— Node Express 時代の標準。500+ ストラテジー。2026年時点で活発なメンテナンスではないが、依然広く使用。モジュラーな OAuth/OIDC を直接組み立てるときに便利。
- **iron-session**(Vercel/community)— 暗号化されたクッキーセッション。別途 DB なしで「クッキーの中にセッションを全部詰める」。Next.js Edge で軽く使うのに向く。
- **jose**(Filip Skokan)— JWT/JWS/JWE/JWK 標準ライブラリ。JWT を自前で発行/検証するときの事実上の標準。
// jose で JWT 発行/検証
const secret = new TextEncoder().encode(process.env.JWT_SECRET!)
const token = await new SignJWT({ sub: 'user-42' })
.setProtectedHeader({ alg: 'HS256' })
.setExpirationTime('15m')
.sign(secret)
const { payload } = await jwtVerify(token, secret)
これら 3 つは大きな SaaS/ライブラリの「内部部品」だ。直接組み立てるチームは減ったが、**API ゲートウェイ**や**マイクロサービス認証**では依然第一線の道具。
12. OAuth フロー — Authorization Code with PKCE が正解
2026年、OAuth フローは次のとおり整理された。
┌─────────────────────────────────────────────────────────────────┐
│ 2026年 OAuth フローごとの推奨 │
│ │
│ Authorization Code + PKCE -> ウェブアプリ、モバイル、SPA │
│ Client Credentials -> サーバ間(M2M) │
│ Device Authorization -> TV/CLI/IoT │
│ Refresh Token Rotation -> すべてのフローと結合 │
│ Resource Owner Password -> 禁止(レガシー互換のみ) │
│ Implicit Flow -> 廃止(PKCE に置換) │
└─────────────────────────────────────────────────────────────────┘
OAuth 2.1(ドラフト、2024〜2025年にかけて RFC プロセスが進行)では Implicit と ROPC が公式に削除された。新コードでは絶対に使わない。
PKCE — SPA/モバイルの必須
PKCE(Proof Key for Code Exchange、RFC 7636)は SPA とモバイルで client_secret を保管できない問題を解く。
1. クライアントが `code_verifier`(ランダム文字列)を生成。
2. SHA256 ハッシュを `code_challenge` として IdP に送信。
3. IdP が `authorization_code` を発行。
4. トークン交換時にクライアントが元の `code_verifier` を送る。
5. IdP がハッシュ比較後、アクセストークン発行。
このフローで**中間者が authorization_code を奪っても**トークン交換ができない。2026年、すべてのモダン IdP/ライブラリがデフォルトで有効化する。
13. パスキー / WebAuthn — 2026年の事実上の標準
2026年時点でパスキー普及は転換点を超えた。
- Apple、Google、Microsoft の 3 OS がすべてパスキーを一級市民として対応。
- 1Password、Bitwarden、Dashlane がクロスデバイスパスキー同期に対応。
- 主要サイト(GitHub、Google、Amazon、Microsoft、eBay、PayPal、X、Best Buy など)がパスキーログインを有効化。
- FIDO Alliance 統計でパスキー認証試行はパスワード比で平均 4 倍速い。
パスキーの仕組み要約
1. 登録時: デバイスが**公開鍵/秘密鍵ペア**を生成。秘密鍵はデバイス(Secure Enclave/TPM)に留まる。
2. サーバは公開鍵だけを受け取る。
3. ログイン時: サーバがチャレンジ(ランダム nonce)を発行。デバイスが秘密鍵で署名。サーバが公開鍵で検証。
4. iCloud Keychain / Google Password Manager によりデバイス間同期可能。
ライブラリ/SaaS 別パスキー対応(2026Q1)
| ソリューション | パスキー対応 | 備考 |
| --- | --- | --- |
| Clerk | 正式 | UI/UX が最も滑らか |
| Stytch | 正式 | ヘッドレス SDK |
| Hanko | 正式(ファースト) | パスキー中心設計 |
| better-auth | プラグイン | 1〜2 行で有効化 |
| SuperTokens | 正式 | セルフホスト時に最も自由 |
| Auth.js v5 | ベータアダプター | 一部制限 |
| WorkOS AuthKit | 正式 | エンタープライズ向け |
SimpleWebAuthn — 自前実装するとき
WebAuthn を直接扱うなら、[SimpleWebAuthn](https://github.com/MasterKale/SimpleWebAuthn) が2026年の事実上の標準ライブラリ。バックエンド(`@simplewebauthn/server`)とブラウザ(`@simplewebauthn/browser`)の両方を提供。
14. マジックリンク / OTP / TOTP — パスワードレスの 3 本柱
**マジックリンク**、**OTP(SMS/メール)**、**TOTP(認証アプリ)**は、パスワードの代替であり MFA の第二要素として使われる。
| 方式 | セキュリティ | UX | コスト | 向いている場面 |
| --- | --- | --- | --- | --- |
| パスキー | 最高(フィッシング耐性) | 最高 | 無料 | すべての新規 |
| TOTP | 高(オフライン) | 中 | 無料 | MFA |
| メール OTP | 中(メールセキュリティ依存) | 中 | 低 | 登録、復旧 |
| マジックリンク | 中(URL 窃取リスク) | 良 | 低 | パスワードレスの一次手段 |
| SMS OTP | 低(SIM スワップ) | 良 | 高 | 最後の砦 |
マジックリンク実装の要点
マジックリンクは**単一使用、短い有効期限、IP/デバイスバインド**が要諦。
// マジックリンクトークン発行
const token = crypto.randomBytes(32).toString('base64url')
const hash = createHash('sha256').update(token).digest('hex')
await db.magicLink.create({
data: {
userId: user.id,
tokenHash: hash, // 原文保存禁止
expiresAt: new Date(Date.now() + 15 * 60 * 1000), // 15分
ip: request.ip,
},
})
const url = `https://example.com/auth/verify?token=${token}`
await sendEmail({ to: user.email, magicLinkUrl: url })
Twilio Verify — SMS OTP の事実上の標準
SMS OTP は自前で実装せず、[Twilio Verify](https://www.twilio.com/docs/verify)、[Vonage](https://www.vonage.com/communications-apis/verify/)、[AWS SNS](https://aws.amazon.com/sns/) のようなマネージドを使うのが一般的。理由:
- 国別 SMS 到達率、キャリアブロック、AUP が複雑。
- キャリアルックアップ、音声 OTP フォールバック。
- SMS 爆撃攻撃の防御(登録フォームで無限 OTP リクエスト)。
2026年時点で SMS 自体のコストは 1 通 $0.01〜$0.10。**トラフィックポンピング(traffic pumping)** 攻撃で月額数千ドル損失の事例が増えた。必ずレート制限 + reCAPTCHA/Turnstile を組み合わせる。
15. セッション vs JWT — 2026年の正解
永遠の議論。2026年の答は明快だ: **セッション > JWT、ただしアクセストークンは短命 JWT**。
比較表
| 観点 | サーバセッション(DB/Redis) | JWT(ステートレス) |
| --- | --- | --- |
| 即時失効 | 可能(行削除) | 不可能(満期まで有効) |
| 検証コスト | DB/Redis ラウンドトリップ | 署名検証だけ |
| スケーラビリティ | Redis クラスタ必要 | 無限(前提: 秘密鍵が安全) |
| データ露出 | クッキーのみ(不透明) | ペイロード base64 露出 |
| 復旧 | 鍵ローテ可能 | 鍵ローテ後に再ログイン |
| 推奨用途 | ユーザーセッション | M2M、短命アクセストークン |
2026年推奨パターン — ハイブリッド
┌─────────────────────────────────────────────────────────┐
│ ハイブリッド推奨フロー │
│ │
│ 1) ログイン後、サーバが発行: │
│ - access_token (JWT, 5〜15分, ペイロードに権限) │
│ - refresh_token (不透明、DB 保存、7〜30日) │
│ │
│ 2) API 呼び出しは access_token で認証 │
│ - 署名検証のみ、DB は見ない │
│ │
│ 3) access 満了時に refresh で更新 │
│ - DB の refresh 行確認後、新 access 発行 │
│ - refresh もローテ — 使ったものは無効化 │
│ │
│ 4) 即時ログアウト時は refresh 行を削除 │
│ - access は自然満了まで有効 │
│ - より速い遮断が要るなら access も短く │
└─────────────────────────────────────────────────────────┘
このパターンは OAuth 2.0 の **refresh token rotation** と同じ。2026年のモダン IdP/ライブラリでデフォルト。
16. トークン保存 — HttpOnly クッキーが正解
ブラウザでトークンをどこに保存するかは永遠の論争だ。
| 保存先 | XSS 安全 | CSRF 安全 | リロード保持 | 推奨 |
| --- | --- | --- | --- | --- |
| **HttpOnly + Secure + SameSite=Lax クッキー** | 安全 | ほぼ安全 | 保持 | ユーザーセッション |
| localStorage | 危険(JS アクセス) | 安全(自動送信なし) | 保持 | 非推奨 |
| sessionStorage | 危険 | 安全 | タブ閉鎖で消失 | 非推奨 |
| メモリ変数 | 安全 | 安全 | リロードで消失 | アクセストークンのみ |
推奨組み合わせ
- セッション ID または refresh token → **HttpOnly + Secure + SameSite=Lax クッキー**。
- アクセストークン → メモリ(ページリロード時に refresh で再発行)。
- またはすべて HttpOnly クッキー(BFF パターン)。
CSRF 防御: SameSite=Lax/Strict + state トークンまたは double-submit cookie。SameSite だけで CSRF が完全防御されるわけではない(同一サイト サブドメイン攻撃、GET の state 変更など)。
17. OWASP A07 — 認証失敗の Top 5 罠
OWASP Top 10 2021 の A07: Identification and Authentication Failures。2026年も生きている罠。
1) ブルートフォース保護の欠如
- ユーザー名/IP/デバイスごとのカウンター。
- 指数バックオフまたは CAPTCHA。
- 5 回失敗で 15 分ロックアウト、10 回失敗で 1 時間、それ以上は管理者介入。
2) アカウント列挙(Account Enumeration)
- ログイン失敗メッセージが「ユーザー不在」/「パスワード違い」で異なってはならない → 常に「メールまたはパスワードが一致しません」。
- 登録時に「すでに登録されたメール」を即時に教えるのも危険 → メール送信で通知。
3) 弱いパスワードポリシー
- NIST 800-63B 推奨: **最小長 8〜12**、**ローテーション強制禁止**(漏洩したら即交換)、**共通パスワードのブロック**(HaveIBeenPwned リスト)。
- 複雑さ強制(特殊文字など)の効果は微小 — 長さの方が重要。
4) セッション固定(Session Fixation)
- ログイン直後にセッション ID を**必ず再発行**。
- 権限昇格時(例: 管理者モード突入)にも再発行。
5) パスワード保存失敗
- bcrypt(コスト 12 以上)、Argon2id、scrypt のいずれかを選択。
- MD5/SHA1/SHA256 単独使用は禁止。PBKDF2 は最低 600,000 反復。
- ソルトはユーザーごとに 16 バイト以上のランダム。
18. B2B 認証要件 — SSO / SCIM / 監査 / IP / MFA 強制
B2B SaaS がエンタープライズ顧客を取りに行くなら次の 5 つがほぼ必須。
1. **SSO(SAML 2.0 + OIDC)** — Okta、Microsoft Entra、Google Workspace などの IdP 連携。
2. **SCIM(System for Cross-domain Identity Management)** — 顧客の IdP でユーザー作成/無効化が自動反映。
3. **監査ログ** — 誰がいつ何をしたか。SOC2、ISO 27001、HIPAA 要件。
4. **IP 許可リスト / 拒否リスト** — 特定 IP 範囲からだけログイン。
5. **MFA 強制** — 組織単位で「MFA 必須」ポリシー。
「エンタープライズ認証税」
B2B SaaS 業界には「エンタープライズ SSO を要求すれば価格が 10 倍」という冗談がある。理由:
- 自前実装が難しい(SAML デバッグの悪夢)。
- WorkOS、Frontegg のような SaaS が SSO 接続あたり $99/月を取る。
- だから SaaS 自体もエンタープライズプランで SSO をロックして $1,000+/月を取る。
ライブラリで作るときは [boxyhq/saml-jackson](https://github.com/boxyhq/jackson) や SuperTokens のマルチテナントモードを検討する価値がある。
19. 韓国の認証 — NAVER · Kakao · PASS · KakaoTalk 認証書
韓国市場に特化した認証フロー。
- **NAVER ログイン** — OAuth 2.0 標準。Auth.js、better-auth に内蔵。
- **Kakao ログイン** — OAuth 2.0。30〜40 代ユーザーの比重が大きい。
- **KakaoTalk ウォレット / 認証書** — モバイル認証。フィンテック/公共。
- **PASS アプリ** — 通信 3 社(SKT、KT、LG U+)の統合本人確認サービス。
- **簡易本人確認** — 携帯電話番号 + 通信会社認証。
- **i-PIN** — 住民番号代替 — 2024 年以降事実上廃止。
- **共同認証書(旧 公認認証書)** — 金融分野。モバイル OS の PASS 認証書で置換中。
Auth.js に NAVER を追加
// auth.ts
export const { auth } = NextAuth({
providers: [
Naver({
clientId: process.env.NAVER_CLIENT_ID!,
clientSecret: process.env.NAVER_CLIENT_SECRET!,
}),
],
})
Kakao も同じパターン。韓国ユーザーが主ターゲットなら両方ほぼ必須。
20. 日本の認証 — LINE · Yahoo!Japan · Mercari · d ACCOUNT
日本市場特化。
- **LINE Login** — メッセンジャー LINE ベース。日本 B2C ではほぼ必須。
- **Yahoo!Japan ID** — Yahoo! JAPAN ユーザーベースが広範。
- **Mercari ID** — メルカリエコシステム。
- **d ACCOUNT(NTT ドコモ)** — 通信会社統合。
- **au ID、SoftBank ID** — 他通信会社。
- **マイナンバーカード** — 公共本人確認。eKYC。
LINE Login の追加
Auth.js に LINE プロバイダがある。日本ユーザー比率が大きいサービス(特に EC、フードデリバリ、ゲーム)は LINE を一次オプションに置くのが標準。
21. ボット防御 — Turnstile · hCaptcha · reCAPTCHA Enterprise · Arkose
CAPTCHA は2026年に、ほぼ見えない方向に進化した。
- **Cloudflare Turnstile** — 無料、見えないチャレンジ。Cloudflare のトラフィックシグナルでボット判定。2026 年の流行 1 位。
- **hCaptcha** — 無料/有料、視覚チャレンジの代替。Cloudflare/Discord などが採用。
- **Google reCAPTCHA Enterprise** — スコアベース(0〜1)、非常に精密。有料。
- **Arkose Labs** — パズルチャレンジ。ボットファーム運営費を高くして阻止。
Cloudflare Turnstile 並列
サーバ検証。
const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
method: 'POST',
body: new URLSearchParams({
secret: process.env.TURNSTILE_SECRET!,
response: token,
remoteip: clientIp,
}),
})
2026年の新規プロジェクトなら Turnstile から検討。無料で UX が最も滑らかだ。
22. AI 時代のボット防御 — パッシブシグナル + 行動分析
LLM 時代に自動化攻撃が爆発した。2026 年のボット防御は次が結合する。
- **パッシブデバイス指紋**(canvas、WebGL、フォント、タイムゾーン)。
- **マウス / キーストロークダイナミクス**。
- **ネットワークシグナル**(IP レピュテーション、ASN、VPN/プロキシ検出、住居 IP vs データセンター)。
- **セッション行動分析**(登録 → ログイン → アクションのシーケンスの統計的異常)。
**Castle**、**Sift**、**Stytch Fraud & Risk**、**Arkose Bot Manager** のようなマネージドがこの領域を埋める。自前実装は非常に難しい。
23. 移行シナリオ — Clerk → Auth.js、Auth0 → Stytch
マネージドからライブラリへ(あるいは別のマネージドへ)の移行は普通のシナリオだ。
Clerk → Auth.js + Postgres
1. Clerk Admin Dashboard でユーザーをエクスポート(JSON)。
2. Postgres に `users`、`accounts`、`sessions` テーブルを作って import。
3. **パスワードハッシュの移行は不可能** — Clerk は自分のハッシュを渡さない。2 つの選択肢:
- 選択肢 A: 全ユーザーに「パスワードリセット」メール送信。
- 選択肢 B: パスワードを捨て、マジックリンク/OAuth のみ許可。
4. OAuth アカウントは `accounts` テーブルの `providerAccountId` で再マッピング。
5. アクティブセッションを失効 → 全員再ログイン。
Auth0 → Stytch
Auth0 はパスワードハッシュをエクスポート時に受け取れる(bcrypt)。Stytch が bcrypt ハッシュ import を受けるためパスワードはそのまま移行可能。
[Stytch Migration Docs](https://stytch.com/docs/api/password-migrate) を参照。
鍵ローテと段階移行
大規模サービスは**二重発行**期間を設ける。
- しばらく Auth0 と Stytch の双方からトークン発行。
- クライアントが新トークンを優先利用、失敗時に旧トークンへフォールバック。
- 一定期間後に旧 IdP 終了。
24. 誰が何を選ぶべきか
地形を全部見たので決定木。
START
│
├─ MVP / サイドプロジェクト / MAU < 10,000?
│ YES -> Auth.js v5 または Clerk Free
│ (Next.js → better-auth 検討)
│
├─ B2C 大規模(MAU 10万+)+ マネージド可?
│ YES -> Clerk または Stytch
│ (価格シミュレーション必須)
│
├─ B2B SaaS のエンタープライズ SSO 必要?
│ YES -> WorkOS(SSO/SCIM)
│ + 自前認証(Auth.js / better-auth)
│ または Stytch B2B / Frontegg 統合
│
├─ データ主権 / セルフホスト必須?
│ YES -> SuperTokens(セルフホスト)
│ または Logto、Ory Network(別記事)
│
├─ パスキー・ファーストでパスワードを無くす?
│ YES -> Hanko または Clerk
│
├─ ミニマル / コード可視性 / 依存最小?
│ YES -> iron-session + jose を組み合わせる
│
└─ 韓国 / 日本ユーザー比率が大きい?
YES -> 上記選択 + NAVER/Kakao(KR)または
LINE/Yahoo!JP(JP)プロバイダを手動追加
エピローグ — 2026 年認証の次の決定点
3 つの大きな流れをまとめる。
1. **パスキーはもはやオプションではない。** 2026 年の新規プロジェクトがパスキーなしで出荷されるのはセキュリティ負債の始まり。Clerk、Stytch、Hanko、better-auth のどれを使うにせよパスキーを ON にする。
2. **MAU 価格モデルをシミュレートする。** Clerk/Stytch/Auth0 の $25〜$99/月は出発単価に過ぎない。MAU 10 万時点の請求書をモデル化し、5 万時点で移行計画を立てておくのが安全。
3. **B2B に向かうなら WorkOS のような SSO レイヤを早めに検討する。** エンタープライズ顧客が SSO を要求するときに自前実装すると 2〜4 週間が SAML デバッグに溶ける。先に敷くのが安い。
> 「認証ライブラリ/SaaS の選択は 6 ヶ月の速い出荷と 5 年の運用コストを同時に決める。速い出だしだけでなく移行コストも一緒に見ること。」
マネージドのなかでもデータポータビリティ(特にパスワードハッシュのエクスポート可否)が 5 年後の自由度を決める。認証をインフラの決定として扱う — データベース選びと同じくらい重く。
参考 / References
- [Auth.js v5 Documentation](https://authjs.dev/)
- [NextAuth.js → Auth.js Migration Guide](https://authjs.dev/getting-started/migrating-to-v5)
- [Lucia auth — github lucia-auth/lucia (maintenance mode)](https://github.com/lucia-auth/lucia)
- [better-auth — Documentation](https://www.better-auth.com/)
- [better-auth GitHub — bekacru/better-auth](https://github.com/bekacru/better-auth)
- [Clerk Documentation](https://clerk.com/docs)
- [Clerk Pricing](https://clerk.com/pricing)
- [Stytch Documentation](https://stytch.com/docs)
- [Stytch B2B Authentication](https://stytch.com/b2b)
- [WorkOS Documentation](https://workos.com/docs)
- [WorkOS Pricing](https://workos.com/pricing)
- [Kinde Documentation](https://kinde.com/docs/)
- [SuperTokens GitHub — supertokens/supertokens-core](https://github.com/supertokens/supertokens-core)
- [Frontegg Documentation](https://docs.frontegg.com/docs)
- [Hanko — Passkey-first OSS](https://www.hanko.io/)
- [Logto — github logto-io/logto](https://github.com/logto-io/logto)
- [Ory Network — Kratos / Hydra / Keto](https://www.ory.sh/)
- [Keycloak](https://www.keycloak.org/)
- [SimpleWebAuthn — MasterKale/SimpleWebAuthn](https://github.com/MasterKale/SimpleWebAuthn)
- [Passport.js](https://www.passportjs.org/)
- [iron-session — vvo/iron-session](https://github.com/vvo/iron-session)
- [jose — panva/jose JWT library](https://github.com/panva/jose)
- [boxyhq/jackson — SAML Jackson](https://github.com/boxyhq/jackson)
- [OAuth 2.1 Draft RFC](https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/)
- [RFC 7636 — PKCE](https://datatracker.ietf.org/doc/html/rfc7636)
- [OWASP Top 10 2021 — A07 Identification and Authentication Failures](https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/)
- [NIST SP 800-63B Digital Identity Guidelines](https://pages.nist.gov/800-63-3/sp800-63b.html)
- [FIDO Alliance — Passkeys](https://fidoalliance.org/passkeys/)
- [Have I Been Pwned — Pwned Passwords](https://haveibeenpwned.com/Passwords)
- [Cloudflare Turnstile](https://www.cloudflare.com/products/turnstile/)
- [hCaptcha](https://www.hcaptcha.com/)
- [Twilio Verify API](https://www.twilio.com/docs/verify)
- [NAVER Login Developers](https://developers.naver.com/products/login/api/api.md)
- [Kakao Login Developers](https://developers.kakao.com/docs/latest/ko/kakaologin/common)
- [LINE Login Developers](https://developers.line.biz/en/docs/line-login/overview/)
- [Yahoo! JAPAN Developer Network — Yahoo ID連携](https://developer.yahoo.co.jp/yconnect/)
현재 단락 (1/462)
2010年代は「ログイン画面くらい自前で作る」がデフォルトだった。2020年代前半は、Auth0 と Firebase Auth が登場し「認証は SaaS にアウトソースする」が主流になった。そして...