@sidebase/nuxt-authのローカル認証を試す

2025/01/13に公開

概要

@sidebase/nuxt-authのローカル認証を試す機会がありましたので、備忘録です。

背景

以下の記事で、@sidebase/nuxt-authを使って、Drupalの認証を行う方法を紹介しました。

https://zenn.dev/nakamura196/articles/66697e95bbbc7b

上記の記事では、Nuxt3のSSRを利用して、@sidebase/nuxt-authのauthjsプロバイダを使用していました。プロバイダの説明は以下です。

authjs: for non-static apps that want to use Auth.js / NextAuth.js to offer the reliability & convenience of a 23k star library to the Nuxt 3 ecosystem with a native developer experience (DX)
local: for static pages that rely on an external backend with a credential flow for authentication. The Local Provider also supports refresh tokens since v0.9.0. Read more here.

(機械翻訳)authjs: 非静的なアプリ向けで、Auth.js / NextAuth.js を使用し、23,000以上のスターを持つ信頼性と利便性をNuxt 3エコシステムに提供します。開発者にネイティブな開発体験 (DX) を提供します。
local: 外部バックエンドを使用し、認証のために資格情報フローを利用する静的ページ向けです。このローカルプロバイダーは、バージョン0.9.0以降、リフレッシュトークンもサポートしています。詳しくはこちらをご覧ください。

アプリケーションをSSGなどで作成した際には、後者の方法を使用する必要があるかと思います。

ソースコード

リポジトリは以下です。

https://github.com/nakamura196/nuxt-auth-local-drupal

ソースコードは以下です。

ローカル認証を使用する場合には、next-authをインストールする必要はなく、@sidebase/nuxt-authのみでよいようでした。

package.json
{
  "name": "nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "dependencies": {
    "nuxt": "^3.15.1",
    "vue": "latest",
    "vue-router": "latest"
  },
  "devDependencies": {
    "@sidebase/nuxt-auth": "^0.9.4"
  }
}

Drupalの認証を使用します。CMS_URLには、https://drupal.example.orgのような値を入れます。

試行錯誤の結果、特にsignIngetSessionを以下のように設定することで、最低限の動作確認ができました。

nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  compatibilityDate: "2024-11-01",
  modules: ["@sidebase/nuxt-auth"],

  auth: {
    baseURL: process.env.CMS_URL + "/",
    provider: {
      type: "local",
      endpoints: {
        signIn: { path: "user/login?_format=json", method: "post" },
        signOut: { path: "user/logout", method: "get" },
        signUp: undefined,
        getSession: {
          path: "session/token",
          method: "get",
        },
      },
      token: {
        signInResponseTokenPointer: "/csrf_token", // トークンの取得元を設定
        type: "Bearer", // トークンの種類(一般的にBearerを使用)
        headerName: "X-CSRF-Token", // ヘッダーにトークンを設定
        maxAgeInSeconds: 3600, // トークンの有効期限(1時間)
      },
    },
  },
});
app.vue
<script setup lang="ts">
const { status, signIn, data, signOut } = useAuth();

const username = ref("");
const password = ref("");

const handleLogin = () => {
  signIn({
    name: username.value,
    pass: password.value,
  });
};
</script>

<template>
  <div>
    <h1>You are currently {{ status }}.</h1>

    <p>{{ data }}</p>

    <div>
      <template v-if="status === 'authenticated'">
        <button @click="signOut()">Sign Out</button>
      </template>
      <template v-else>
        <form @submit.prevent="handleLogin">
          <input type="text" v-model="username" placeholder="ユーザ名" />
          <input type="password" v-model="password" placeholder="パスワード" />
          <button type="submit">Sign In</button>
        </form>
      </template>
    </div>
  </div>
</template>

挙動

以下のようなログインフォームが表示されます。ユーザ名とパスワードを入力します。

statusloadingになります。

結果、以下のように表示されます。今回の実装ではdataに設定されるセッショントークンが表示されます。

まとめ

getSessionのエンドポイントは他のものにしたほうがよいかと思いますが、@sidebase/nuxt-authのローカル認証について、参考になりましたら幸いです。

Discussion