環境
- nuxt 3.11
- @sidebase/nuxt-auth 0.7.0
はじめに
Nuxt3 で認証機能を実装するには幾つか選択肢がありますが、その中でSidebase Nuxt Auth
を実装しました。選択した際の経緯と実装方法の紹介です。
Auth Module
Nuxt2にはnuxt/authという公式の認証機能があったようですがNuxt3には対応しておらず、代わりに以下の方法が紹介されています。
- Sidebase Nuxt Auth based on next-auth
- AuthJs Nuxt based on Auth.js
- Implement your own auth using Lucia or Nuxt Auth Template
独自認証は最後の手段として、Authjs Nuxt
はあまり更新されていませんでした。
Sidebase Nuxt Auth
は人気で更新頻度も高かったため今回利用することに決めました。
インストール
公式ページに従ってインストールします。
npx nuxi@latest module add sidebase-auth
実装
公式ページにQuickStartがあるためこれに従って実装していきます。
nuxt.config.ts
にProviderタイプを設定します。今回はauthjs
を設定しますが、バックエンドAPIを用意する場合はlocal
やrefresh
が利用できます。
export default defineNuxtConfig({
modules: ['@sidebase/nuxt-auth'],
auth: {
provider: {
type: 'authjs'
}
}
})
次に認証関連のリクエストを処理するための認証ハンドラーを作成します。server/api/auth/[...].ts
ファイルを作成します。
import { NuxtAuthHandler } from '#auth'
import GithubProvider from 'next-auth/providers/github'
export default NuxtAuthHandler({
pages: {
signIn: "/login", // ログインページ
},
providers: [
// @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point
GithubProvider.default({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET
})
]
})
authjs
で使用できる認証プロバイダは NextAuth.js で確認できます。
ログインページ
signInで指定したログインページでログインできるようにします。
<template>
<h1>ログイン</h1>
<button @click="signIn('github')" type="submit">Githubでログイン</button>
<p>Status: {{ status }}</p>
</template>
<script lang="ts" setup>
const { status, data, signIn } = useAuth();
</script>
sighnIn
を呼ぶと認証ページに飛びます。status
で認証状態を確認できます。
アクセス制限
nuxt.config.ts
でglobalAppMiddleware:true
を設定することで全体に認証制限を設定できます。これで認証前にアクセスするとログインページへリダイレクトされるようになります。
ですが、これだけだとすべてのページで制限されるため、ログインページでも延々とリダイレクトします。
ログインページをauth: false
で認証不要にするか、unauthenticatedOnly: true
で認証前のみアクセスできるようにします。
export default defineNuxtConfig({
modules: ['@sidebase/nuxt-auth'],
auth: {
globalAppMiddleware: true,
provider: {
type: 'authjs'
}
}
})
<script setup lang="ts">
definePageMeta({
auth: {
unauthenticatedOnly: true,
navigateAuthenticatedTo: "/home", // 認証済みのリダイレクト先
},
});
</script>
これでログイン後home画面に遷移するのが確認できるかと思います。