🌩️

Cloudflare WorkersでAuth.jsを使うときのハマりポイント

に公開

TL;DR

  • Auth.js v4はNode.js依存のため、Cloudflare Workers(Edge Runtime)では動作しない
  • Auth.js v5はEdge Runtime対応だが、特定のバージョンで問題が発生
  • next-auth@5.0.0-beta.4以降でtrustHost: trueの設定が必須
  • HTTPSモジュール依存からfetch API依存への根本的な設計変更が必要

はじめに:Edge環境での認証実装の落とし穴

Next.jsアプリケーションをCloudflare Workersにデプロイする際、最も厄介な問題の1つが認証の実装だと思います。

開発環境(Node.js): ✅ 完璧に動作
本番環境(Edge Runtime): ❌ 謎のエラーで動かない

この記事では、Auth.js v4からv5への移行で遭遇した具体的なエラーと、その解決方法を詳しく解説しようと思います。

環境と前提条件

プロジェクト環境:
  - Next.js: 15.0.4
  - デプロイ先: Cloudflare Workers
  - ビルドツール: @opennextjs/cloudflare
  - 認証プロバイダー: Okta
  
要件:
  - SSO(シングルサインオン)必須
  - Edge環境での高速レスポンス
  - サーバーレスでのコスト最適化

問題1:Auth.js v4がEdge環境で動作しない

Node.js APIの不在

# Auth.js v4での実装
npm install next-auth@^4.24.0

(バージョンを指定しなければ、v4系がインスコされるはずです。)

開発環境では完璧に動作していたコードが、Cloudflare Workersにデプロイした際のエラー

[unenv] https.request is not implemented yet!
[unenv] buffer.Buffer() is not implemented yet!

Error: There was a problem with the server configuration. 
Check the server logs for more information.

根本原因:Auth.js v4のアーキテクチャ

Auth.js v4の内部実装を調査すると、以下の問題が判明

// Auth.js v4の内部実装(簡略化)
const https = require('https');
const { Buffer } = require('buffer');

// OAuthプロバイダーとの通信
function makeOAuthRequest(url, options) {
  return new Promise((resolve, reject) => {
    const req = https.request(url, options, (res) => {
      // Node.js固有のStream API使用
      let data = Buffer.alloc(0);
      res.on('data', (chunk) => {
        data = Buffer.concat([data, chunk]);
      });
    });
  });
}

問題点

  • httpsモジュール:Node.js固有のAPI
  • Buffer:Node.js固有のバイナリデータ処理
  • Stream API:Edge Runtimeには存在しない

Cloudflare WorkersのランタイムとNode.jsの違い

機能 Node.js Cloudflare Workers
実行環境 V8 + Node.js APIs V8 + Web APIs
HTTPクライアント http/https fetch
バイナリ処理 Buffer ArrayBuffer/Uint8Array
ファイルシステム fs ❌ 利用不可
データ処理 Stream API Web Streams API

問題2:Auth.js v5の初期バージョンでの問題

v5への移行開始

# Auth.js v5(beta)へのアップグレード
npm uninstall next-auth
npm install next-auth@beta

新たなエラー:ホスト検証の問題

UntrustedHost: Host must be trusted. URL was: https://my-app.workers.dev/api/auth/session. 
Read more at https://errors.authjs.dev#untrustedhost

バージョン別の動作検証

実際に検証したバージョンと結果:

バージョン Edge対応 ホスト検証 結果
v4.24.7 - Node.js依存でエラー
v5.0.0-beta.3 緩い ✅ 動作(但し非推奨)
v5.0.0-beta.4以降 厳格 trustHost未設定でエラー
v5.0.0-beta.4以降 厳格 trustHost: trueで解決

技術的背景:なぜホスト検証が強化されたのか

// Auth.js v5.0.0-beta.4での変更
function assertOrigin(request: Request) {
  const url = new URL(request.url);
  const origin = request.headers.get("Origin");
  
  // Edge環境でのセキュリティ強化
  if (process.env.AUTH_TRUST_HOST !== "true") {
    if (!origin || origin !== url.origin) {
      throw new UntrustedHost(
        `Host must be trusted. URL was: ${url}`
      );
    }
  }
}

この変更により、CSRF攻撃に対するセキュリティは向上しましたが、Edge環境では予期しない問題が発生しました。

解決策:正しい設定と実装方法

ステップ1:適切なバージョンの選択

{
  "dependencies": {
    "next-auth": "5.0.0-beta.29"  // 最新の安定版を使用
  }
}

ステップ2:Edge環境対応の設定

// auth.config.ts
import type { NextAuthConfig } from "next-auth"
import Okta from "next-auth/providers/okta"

export const authConfig = {
  providers: [
    Okta({
      clientId: process.env.OKTA_CLIENT_ID,
      clientSecret: process.env.OKTA_CLIENT_SECRET,
      issuer: process.env.OKTA_ISSUER,
    }),
  ],
  // Edge環境での必須設定
  trustHost: true,
  
  // Edge環境でのセッション戦略
  session: {
    strategy: "jwt",  // 今回はDBレスで実装 
  },
  
  // デバッグ情報(開発時のみ)
  debug: process.env.NODE_ENV === "development",
} satisfies NextAuthConfig  // パッケージ名はnext-authのまま

Edge環境特有の注意点とベストプラクティス

1. fetch APIの活用

// Edge環境対応
const response = await fetch('https://api.example.com', {
  headers: {
    'Authorization': `Bearer ${token}`
  }
})

2. セッション管理の最適化

// Edge環境でのJWTカスタマイズ
callbacks: {
  async jwt({ token, account, profile }) {
    if (account && profile) {
      // 最小限の情報のみ保存(JWTサイズ削減)
      token.id = profile.sub
      token.email = profile.email
      // ❌ 大きなオブジェクトは避ける
      // token.fullProfile = profile
    }
    return token
  },
}

まとめ:Edge環境での認証実装のポイント

  1. 正しいバージョン選択:Auth.js v5.0.0-beta.4以降を使用
  2. trustHost設定:Edge環境では必須
  3. JWT戦略:データベース不要でEdge環境に最適
  4. fetch API活用:Node.js APIを避ける

今後の展望

Auth.jsは急速に進化しており、Edge環境のサポートも継続的に改善されているようなので、定期的なアップデートとリリースノートの確認が重要だと感じました。

参考リソース


この記事で紹介したコードは、実際の本番環境で動作確認済みです。Edge環境での認証実装に悩んでいる方の参考になれば幸いです。

GENDA

Discussion