6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsでsrc/appディレクトリを使っている場合にサクッとBASIC認証つける

Posted at

概要

Next.jsで作成したサイトを一部の人しか見れないようにするため、
大したものじゃなくて良いけど一応パスワードかけときたいなと思い、方法を検索。

Vercelのオプションでパスワード認証があったけど、高すぎる。
かといってNextAuth.jsは正直難しそうだったため、middlewareで簡易的な設定を決意。

しかし、検索してると出てくる情報が、
middlewareフォルダを作って、そこにmiddleware.tsを置くべきあったり、
または、pages/下層にmiddleware.tsを置くとあるが、
src/appディレクトリを使っている場合はどうすればええんや等、
初学者には色々と悩むポイントがあったのでここに備忘録としてまとめておく。

結論

src下層にmiddleware.tsを直接置けば機能する。

ディレクトリ構成(おおよそのものを表示)
プロジェクトルート
│
├── public/             # 静的ファイル
│
├── src/                # ソースコード
│   ├── app/            # アプリケーションファイル
│   └── middleware.ts   # ミドルウェア(これ)
│
├── package.json        # パッケージ設定
└── tsconfig.json       # TypeScript設定

middleware.tsのコードは下記にすれば良い。

サンプルコード(パスワード直書きパターン)
// Next.jsのサーバーサイドルーティング機能から必要な型をインポート
import { NextRequest, NextResponse } from 'next/server';

// ミドルウェアの設定。全てのルート('/')でこのミドルウェアを適用
export const config = {
    matcher: ['/']
};

// ミドルウェア関数を定義。NextRequestオブジェクトを受け取る
export function middleware(request: NextRequest) {
    // リクエストヘッダーからauthorizationを取得
    const basicAuth = request.headers.get('authorization');

    if (basicAuth) {
        // Basic認証の値をデコードしてユーザー名とパスワードを取得
        const authValue = basicAuth.split(' ')[1];
        const [user, password] = atob(authValue).split(':');

        // 正しいユーザー名とパスワードが提供された場合、リクエストを次の処理へ進める
        if (user === 'username' && password === 'password') {
            return NextResponse.next();
        }
    }

    // 認証に失敗した場合、リダイレクト応答を返す
    // ここでリダイレクト先のURLを指定します。例えば、'/'へのリダイレクト
    return NextResponse.redirect('/');
}

環境変数から取得する場合は下記。
(もちろんこちらの方が良い)

.サンプルコード(env.localから取得する場合)
// Next.jsのサーバーサイドルーティング機能から必要な型をインポート
import { NextRequest, NextResponse } from 'next/server';

// ミドルウェアの設定。全てのルート('/')でこのミドルウェアを適用
export const config = {
    matcher: ['/']
};

// ミドルウェア関数を定義。NextRequestオブジェクトを受け取る
export function middleware(request: NextRequest) {
    // リクエストヘッダーからauthorizationを取得
    const basicAuth = request.headers.get('authorization');

    if (basicAuth) {
        // Basic認証の値をデコードしてユーザー名とパスワードを取得
        const authValue = basicAuth.split(' ')[1];
        const [user, password] = atob(authValue).split(':');

        // 環境変数から正しいユーザー名とパスワードを取得
        const envUser = process.env.AUTH_USER;
        const envPassword = process.env.AUTH_PASSWORD;

        // 環境変数の値と一致する場合、リクエストを次の処理へ進める
        if (user === envUser && password === envPassword) {
            return NextResponse.next();
        }
    }

    // 認証に失敗した場合、リダイレクト応答を返す
    // ここでリダイレクト先のURLを指定します。例えば、'/'ページへのリダイレクト
    return NextResponse.redirect('/');
}

結果

ローカル環境であってもVercel環境であっても認証を求められるようになった。

image.png

6
2
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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?