セッションと認証
はじめに
このレシピでは、フルスタックのNuxtアプリで認証を設定します。Nuxt Auth Utilsこれは、クライアント側とサーバー側のセッションデータを管理するための便利なユーティリティを提供します。
このモジュールは、セッションデータを保存するために保護された密封型クッキーを使用するため、セッションデータを保存するためのデータベースを設定する必要はありません。
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 === '[email protected]' && password === 'iamtheadmin') {
// set the user session in the cookie
// this server util is auto-imported by the auth-utils module
await setUserSession(event, {
user: {
name: 'John Doe',
},
})
return {}
}
throw createError({
statusCode: 401,
message: 'Bad credentials',
})
})
zod依存関係をインストールしていることを確認してください (npm i zod)。ログインページ
このモジュールは、アプリケーションでユーザーが認証されているかどうかを知るためのVueコンポーザブルを公開します。
<script setup>
const { loggedIn, session, user, clear, fetch } = useUserSession()
</script>
/api/loginルートにログインデータを送信するためのフォームを持つログインページを作成しましょう。
<script setup lang="ts">
const { loggedIn, user, fetch: refreshSession } = useUserSession()
const credentials = reactive({
email: '',
password: '',
})
async function login () {
try {
await $fetch('/api/login', {
method: 'POST',
body: credentials,
})
// Refresh the session on client-side and redirect to the home page
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) => {
// make sure the user is logged in
// This will throw a 401 error if the request doesn't come from a valid user session
const { user } = await requireUserSession(event)
// TODO: Fetch some stats based on the user
return {}
})
アプリのルートを保護する
サーバー側のルートが適切に設定されているため、データは安全ですが、他に何もせずに認証されていないユーザーが/usersページにアクセスしようとすると、おそらく奇妙なデータが表示されるでしょう。そのため、クライアント側のミドルウェアを作成して、クライアント側でルートを保護し、ユーザーをログインページにリダイレクトする必要があります。
nuxt-auth-utilsは、ユーザーがログインしているかを確認し、ログインしていない場合はリダイレクトするために使用する便利なuseUserSessionコンポーザブルを提供します。
/middlewareディレクトリにミドルウェアを作成します。サーバーとは異なり、クライアント側のミドルウェアはすべてのエンドポイントに自動的に適用されるわけではないため、適用したい場所を指定する必要があります。
export default defineNuxtRouteMiddleware(() => {
const { loggedIn } = useUserSession()
// redirect the user to the login screen if they're not authenticated
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データベースまたはNuxtHub SQLデータベース
- ユーザーにメールとパスワードでサインアップさせるには、パスワードハッシュ化
- のサポートを追加するWebAuthn / Passkeys
オープンソースのatidoneリポジトリをチェックして、OAuth認証、データベース、CRUD操作を備えたNuxtアプリの完全な例を確認してください。