🙆‍♀️

Nuxt3と@sidebase/nuxt-authを使って、Drupalの認証を行う

2025/01/12に公開

概要

Nuxt3と@sidebase/nuxt-authを使って、Drupalの認証を行う方法です。

背景

以下の記事で、GakuNin RDMの認証を行う方法を紹介しました。

https://zenn.dev/nakamura196/articles/4e43c3f18c8b99

また、以下の記事で、Next.jsからDrupalのOAuthを利用する方法を紹介しました。

https://zenn.dev/nakamura196/articles/47bb019c792f52

これらを参考にして、Nuxt3からDrupalのOAuthを利用します。

方法

ソースコードは以下のリポジトリでご確認いただけます。

https://github.com/nakamura196/nuxt-rdm

具体的には、以下です。

https://github.com/nakamura196/nuxt-rdm/blob/main/server/api/auth/[...].ts

{
      id: "drupal",
      name: "Drupal",
      type: "oauth",
      clientId: useRuntimeConfig().drupalClientId,
      clientSecret: useRuntimeConfig().drupalClientSecret,
      authorization: {
        url: process.env.DRUPAL_AUTH_URL,
        params: {
          scope: process.env.DRUPAL_SCOPE,
          response_type: "code",
          redirect_uri: `${
            useRuntimeConfig().nextAuthUrl
          }/api/auth/callback/drupal`,
        },
      },
      token: {
        async request(context) {
          const body = new URLSearchParams({
            client_id: useRuntimeConfig().drupalClientId,
            client_secret: useRuntimeConfig().drupalClientSecret,
            code: context.params.code || "",
            grant_type: "authorization_code",
            redirect_uri: `${
              useRuntimeConfig().nextAuthUrl
            }/api/auth/callback/drupal`,
          });

          const res = await fetch(process.env.DRUPAL_TOKEN_URL || "", {
            method: "POST",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
            },
            body,
          });

          const json = await res.json(); // Parse the response body once

          if (!res.ok) {
            throw new Error(`Token request failed: ${res.statusText}`);
          }

          return { tokens: json };
        },
      },
      profile(profile) {
        return {
          id: profile.sub, // "sub" をユーザーの一意のIDとして利用
          name: profile.name || profile.preferred_username || "Unknown User", // 名前の優先順位を設定
          email: profile.email || "No Email Provided", // メールがない場合のフォールバック
          image: profile.profile || null, // プロファイルURLを画像として使用(必要に応じて調整)
        };
      },
    },

まとめ

間違っている点もあるかもしれませんが、参考になりましたら幸いです。

Discussion