セッションと認証
認証はウェブアプリで非常に一般的な要件です。このレシピでは、Nuxtアプリで基本的なユーザー登録と認証を実装する方法を紹介します。
はじめに
このレシピでは、Nuxt Auth Utilsを使用してフルスタックのNuxtアプリで認証を設定します。このモジュールは、クライアントサイドとサーバーサイドのセッションデータを管理するための便利なユーティリティを提供します。
このモジュールはセッションデータを保存するためにセキュアでシールドされたクッキーを使用するため、セッションデータを保存するためのデータベースを設定する必要はありません。
nuxt-auth-utilsのインストール
nuxt
CLIを使用してnuxt-auth-utils
モジュールをインストールします。
npx nuxt module add auth-utils
このコマンドはnuxt-auth-utils
を依存関係としてインストールし、nuxt.config.ts
のmodules
セクションに追加します。
クッキー暗号化キー
nuxt-auth-utils
はシールドされたクッキーを使用してセッションデータを保存するため、セッションクッキーはNUXT_SESSION_PASSWORD
環境変数からの秘密キーを使用して暗号化されます。
設定されていない場合、この環境変数は開発モードで実行中に自動的に.env
に追加されます。
NUXT_SESSION_PASSWORD=a-random-password-with-at-least-32-characters
デプロイ前にこの環境変数を本番環境に追加する必要があります。
ログインAPIルート
このレシピでは、静的データに基づいてユーザーをサインインするためのシンプルなAPIルートを作成します。
メールアドレスとパスワードをリクエストボディに含むPOSTリクエストを受け入れる/api/login
APIルートを作成しましょう。
import { z } from 'zod'
const bodySchema = z.object({
email: z.string().email(),
password: z.string().min(8)
})
export default defineEventHandler(async (event) => {
const { email, password } = await readValidatedBody(event, bodySchema.parse)
if (email === 'admin@admin.com' && password === 'iamtheadmin') {
// クッキーにユーザーセッションを設定
// このサーバーユーティリティはauth-utilsモジュールによって自動インポートされます
await setUserSession(event, {
user: {
name: 'John Doe'
}
})
return {}
}
throw createError({
statusCode: 401,
message: 'Bad credentials'
})
})
プロジェクトにzod
依存関係をインストールすることを忘れないでください(npm i zod
)。
nuxt-auth-utils
によって公開されているsetUserSession
サーバーヘルパーについてもっと読む。
ログインページ
このモジュールは、アプリケーション内でユーザーが認証されているかどうかを知るためのVueコンポーザブルを公開しています。
const { loggedIn, session, user, clear, fetch } = useUserSession()
/api/login
ルートにログインデータを送信するフォームを持つログインページを作成しましょう。
<script setup lang="ts">
const { loggedIn, user, fetch: refreshSession } = useUserSession()
const credentials = reactive({
email: '',
password: '',
})
async function login() {
$fetch('/api/login', {
method: 'POST',
body: credentials
})
.then(async () => {
// クライアントサイドでセッションを更新し、ホームページにリダイレクト
await refreshSession()
await navigateTo('/')
})
.catch(() => alert('Bad credentials'))
}
</script>
<template>
<form @submit.prevent="login">
<input v-model="credentials.email" type="email" placeholder="Email" />
<input v-model="credentials.password" type="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
</template>
APIルートの保護
サーバールートを保護することは、データを安全に保つための鍵です。クライアントサイドのミドルウェアはユーザーにとって便利ですが、サーバーサイドの保護がなければデータにアクセスされる可能性があります。機密データを含むルートを保護することは重要であり、ユーザーがログインしていない場合は401エラーを返すべきです。
auth-utils
モジュールは、ユーザーがログインしてアクティブなセッションを持っていることを確認するためのrequireUserSession
ユーティリティ関数を提供します。
認証されたユーザーのみがアクセスできる/api/user/stats
ルートの例を作成しましょう。
export default defineEventHandler(async (event) => {
// ユーザーがログインしていることを確認
// 有効なユーザーセッションからのリクエストでない場合、401エラーをスローします
const { user } = await requireUserSession(event)
// TODO: ユーザーに基づいていくつかの統計を取得
return {}
});
アプリルートの保護
サーバーサイドルートがあることでデータは安全ですが、何もしなければ、認証されていないユーザーが/users
ページにアクセスしようとすると奇妙なデータを取得する可能性があります。クライアントサイドでルートを保護し、ユーザーをログインページにリダイレクトするためのクライアントサイドミドルウェアを作成する必要があります。
nuxt-auth-utils
は、ユーザーがログインしているかどうかを確認し、ログインしていない場合にリダイレクトするための便利なuseUserSession
コンポーザブルを提供します。
/middleware
ディレクトリにミドルウェアを作成します。サーバーとは異なり、クライアントサイドのミドルウェアはすべてのエンドポイントに自動的に適用されるわけではなく、適用したい場所を指定する必要があります。
export default defineNuxtRouteMiddleware(() => {
const { loggedIn } = useUserSession()
// 認証されていない場合、ユーザーをログイン画面にリダイレクト
if (!loggedIn.value) {
return navigateTo('/login')
}
})
ホームページ
ルートを保護するためのアプリミドルウェアができたので、認証されたユーザー情報を表示するホームページで使用できます。ユーザーが認証されていない場合、ログインページにリダイレクトされます。
保護したいルートにミドルウェアを適用するためにdefinePageMeta
を使用します。
<script setup lang="ts">
definePageMeta({
middleware: ['authenticated'],
})
const { user, clear: clearSession } = useUserSession()
async function logout() {
await clearSession()
await navigateTo('/login')
}
</script>
<template>
<div>
<h1>Welcome {{ user.name }}</h1>
<button @click="logout">Logout</button>
</div>
</template>
また、セッションをクリアしてログインページにリダイレクトするためのログアウトボタンも追加しました。
結論
Nuxtアプリで非常に基本的なユーザー認証とセッション管理を設定することに成功しました。また、認証されたユーザーのみがアクセスできるように、サーバーとクライアントサイドで機密ルートを保護しました。
次のステップとして、以下を行うことができます:
- 20以上のサポートされているOAuthプロバイダーを使用して認証を追加
- ユーザーを保存するためのデータベースを追加、Nitro SQL DatabaseまたはNuxtHub SQL Databaseを参照
- パスワードハッシュ化を使用してメールとパスワードでユーザー登録を許可
- WebAuthn / Passkeysのサポートを追加
OAuth認証、データベース、CRUD操作を備えたNuxtアプリの完全な例については、オープンソースのatidoneリポジトリをチェックしてください。
※このページは Nuxt.js 公式ドキュメントの翻訳ページ(非公式)です。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/3.x/guide/recipes/sessions-and-authentication