🌩️

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環境のサポートも継続的に改善されているようなので、定期的なアップデートとリリースノートの確認が重要だと感じました。

参考リソース

追記

Auth.js(旧 NextAuth.js)は、今後 Better Auth チームによってメンテナンス・運営されることになったとのことです。新しいプロジェクトを始める場合は、 Better Auth を推奨します。
(データベースなしでステートレスなセッション管理も、Better Auth の機能として取り込む予定)

Auth js is now part of Better Auth. We recommend new projects to start with Better Auth unless there are some very specific feature gaps (most notably stateless session management without a database).

ref: https://github.com/nextauthjs/next-auth/blob/main/README.md

better-auth 側のページ
https://www.better-auth.com/blog/authjs-joins-better-auth


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

GENDA

Discussion