0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nextjs-auth0のヘルパーメソッドを使ってログイン処理をスキップする

Posted at

Next.js × Auth0でアプリを開発しています。
Next.jsではServer Componentを採用しており、Playwrightでコンポーネント統合テスト1を実施しています。
しかし毎回ログイン画面に遷移して、IDとパスワードを入力するのは時間も手間もかかって大変でした。

そこで、nextjs-auth0のヘルパーメソッドを使って、ログイン状態をスキップできる方法を試してみることにしました。

nextjs-auth0のヘルパーでログイン状態を作る

nextjs-auth0にはテスト用のユーティリティとして、generateSessionCookieというメソッドが提供されています。

これは、Auth0の認証フローにて、IDトークンとアクセストークンを疑似的に再現することで、ログイン後のセッション情報を作成できます。

Auth0の認証フローをもとに作成

このセッションCookieを用意することで、ログイン状態が必要なページ(middleware.tsなどで保護されているルート)に対しても、ログイン済みとしてアクセスできるようになります。

middleware.ts
import { NextRequest, NextResponse } from "next/server"
import { auth0 } from "@/lib/auth0"

export async function middleware(request: NextRequest) {
  const authRes = await auth0.middleware(request)

  if (request.nextUrl.pathname.startsWith("/auth")) {
    return authRes
  }

  // ここでログイン状態かを確認している
  const session = await auth0.getSession(request)
  if (!session) {
    // user is not authenticated, redirect to login page
    return NextResponse.redirect(new URL("/auth/login", request.nextUrl.origin))
  }

  // the headers from the auth middleware should always be returned
  return authRes
}

※ nextjs-auth0のExamples.mdのAccessing the authenticated userのサンプルを記載

実装例

開発環境

  • TypeScript : 5.8.3
  • Next.js 15.2.4
  • playwright/test 1.51.0
  • nextjs-auth0 4.4.1

nextjs-auth0 4.4.1を活用しています。
最新版(4.4.2)では不具合2が発生しており、動作していません。

サンプルコード

Playwrightのfixtureにて、sessionを疑似生成し、playwrightでcookieに追加3します。

login.ts

import { test as base, Page } from "@playwright/test";

export const test = base.extend<{ page: Page }>({
  page: async ({ browser }, use) => {
    const context = await browser.newContext();

    // MEMO: ESModuleをサポートしていないため、Auth0のテスト用モジュールを動的にインポート
    const { generateSessionCookie } = await import("@auth0/nextjs-auth0/testing");
    const sessionCookieValue = await generateSessionCookie(
      {
        user: {
          sub: `auth0|${Math.floor(Math.random() * 1000000).toString()}`,
          name: "Sample",
          email: "sample@example.com",
        },
        tokenSet: {
          accessToken: Math.floor(Math.random() * 1000000).toString(),
          expiresAt: Math.floor(Date.now() / 1000) + 3600,
        },
      },
      {
        secret: process.env.AUTH0_SECRET!,
      },
    );

    // 疑似作成したセッションをCookieに追加
    await context.addCookies([
      {
        name: "appSession",
        value: sessionCookieValue,
        domain: "localhost",
        path: "/",
        httpOnly: true,
        secure: false,e
        sameSite: "Lax",
      },
    ]);
    const page = await context.newPage();

    await use(page);

    await context.close();
  },
});

export { expect } from '@playwright/test';

あとは作成したfixtureをテストで利用します。

sample.spec.ts

import { test, expect } from './login';

test('sample test', async ({ page }) => {
  await page.goto("/user"); // ログイン処理を飛ばしている
  await expect(page.getByTestId('title')).toContainText("Sample Title);
});

この方法により、毎回IDとパスワードを入力せずにテストできるようになり、本来確認したい処理や画面遷移のテストに集中できます。

参考情報

  1. コンポーネント間のインターフェース、および相互処理に焦点を当てる。コンポーネント統合テストは、ボトムアップ、トップダウン、ビックバンといった統合戦略のアプローチに大きく依存する(ISTQBテスト技術者資格制度
    Foundation Level シラバス 日本語版 Version 2023V4.0.J02 2.2.1 テストレベル)

  2. https://github.com/auth0/nextjs-auth0/issues/1945

  3. https://playwright.dev/python/docs/next/api/class-browsercontext#browser-context-add-cookies

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?