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?

【3分で実装】Next.jsで超シンプルなBasic認証をmiddleware.tsだけで爆速構築する方法

Posted at

はじめに

「社内ツールやステージング環境にBasic認証かけたい」
でも、大げさな仕組みはいらん!
そんなあなたに朗報です。

Next.jsなら、たった1つのファイル(middleware.ts)でBasic認証を爆速実装できます。
しかもコピペOK。

APIはフロントから認証済みならスルー!みたいな現場のリアルなニーズにも即対応。
現場で役立つコピペコード、置いていきます。

完成イメージ

URL 認証
/ 必要
/dashboard 必要
/api/* 認証スルー

実装手順

1. Next.jsプロジェクト作成

npx create-next-app@latest my-basic-auth-app
cd my-basic-auth-app

2. 環境変数に認証情報セット

.env.local

BASIC_AUTH_USER=myuser
BASIC_AUTH_PASS=mypass

3. middleware.tsを作成

プロジェクト直下にmiddleware.tsを作成。

import { NextResponse } from 'next/server'

const USERNAME = process.env.BASIC_AUTH_USER || 'user'
const PASSWORD = process.env.BASIC_AUTH_PASS || 'password'

const SKIP_AUTH_PATHS = ['/api']

export function middleware(request: Request) {
  const { pathname } = new URL(request.url)

  if (SKIP_AUTH_PATHS.some(path => pathname.startsWith(path))) {
    return NextResponse.next()
  }

  const authHeader = request.headers.get('authorization')
  if (!authHeader) {
    return new NextResponse('Unauthorized', {
      status: 401,
      headers: { 'WWW-Authenticate': 'Basic realm="Secure Area"' },
    })
  }

  const base64Credentials = authHeader.split(' ')[1]
  const [username, password] = atob(base64Credentials).split(':')

  if (username !== USERNAME || password !== PASSWORD) {
    return new NextResponse('Unauthorized', {
      status: 401,
      headers: { 'WWW-Authenticate': 'Basic realm="Secure Area"' },
    })
  }

  return NextResponse.next()
}

4. Next.js再起動して完成

npm run dev

5. 動作確認

  • / にアクセス → Basic認証が出ればOK
  • /api にアクセス → 認証スルーでOK

なんでこの方法が神なの?

他の方法 面倒ポイント
Next.js API Routesで認証 /apiだけならOK、ページ毎にガードは面倒
Auth0などの外部認証 設定が多すぎて萎える
nginxでBasic認証 Vercelに乗せると無理ゲー

→ Next.js公式機能(middleware)だけで実現するこの方法は最強です。

まとめ

やること ファイル
認証ロジック middleware.ts
環境変数読み込み Next.js標準機能

3分で完成するので、ステージングや簡単な管理画面ならこれで即解決!

コピペ用まとめ

import { NextResponse } from 'next/server'

const USERNAME = process.env.BASIC_AUTH_USER || 'user'
const PASSWORD = process.env.BASIC_AUTH_PASS || 'password'

const SKIP_AUTH_PATHS = ['/api']

export function middleware(request: Request) {
  const { pathname } = new URL(request.url)
  if (SKIP_AUTH_PATHS.some(path => pathname.startsWith(path))) {
    return NextResponse.next()
  }

  const authHeader = request.headers.get('authorization')
  if (!authHeader) {
    return new NextResponse('Unauthorized', {
      status: 401,
      headers: { 'WWW-Authenticate': 'Basic realm="Secure Area"' },
    })
  }

  const base64Credentials = authHeader.split(' ')[1]
  const [username, password] = atob(base64Credentials).split(':')

  if (username !== USERNAME || password !== PASSWORD) {
    return new NextResponse('Unauthorized', {
      status: 401,
      headers: { 'WWW-Authenticate': 'Basic realm="Secure Area"' },
    })
  }

  return NextResponse.next()
}

おまけ

VercelでもHerokuでも動きます

この方法ならVercel, Heroku, AWS Lambdaどこでもそのまま動くので、インフラに依存しません。
Next.jsさえ動けばOK。

まとめのまとめ

3分でできてシンプル最強。これ以上ラクなBasic認証は存在しません。

もしよければ

⭐ストック & いいねお願いします!
フォローも大歓迎です。
他にもNext.js小ネタいっぱい投稿してます。

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?