Nuxt 3 の Basic 認証モジュールを作成する
Nuxt 3 は Nuxt 本体の機能拡張を行う "モジュール" の作成がとても簡単になりました。
便利なツールが豊富に用意されていますので、ぜひみんなで Nuxt のエコシステムを大きくしていきましょう。
Nuxt Basic Authentication Module について
Nuxt は Nitro により http サーバーを含んだ形でアプリケーションをビルドすることができます。
SSR(ISG) をするにあたっても Express 等を用意する必要がなくなりました。
そのため本番環境・ステージング環境とも Vercel や Netlify のような環境のみで用意する人も多いのではないでしょうか。
Nuxt Basic Authentication Module は「ステージング環境でBasic認証をかけたい」というときに、とても役に立つモジュールです。
※ Nuxt 3 専用です
使い方
nuxt.config.ts
にて Nuxt Basic Auth Module を読み込み、必要に応じてオプションを設定すると、自動的に Basic 認証がかかります。
import { defineNuxtConfig } from 'nuxt'
import BasicAuth from 'nuxt-basic-authentication-module'
export default defineNuxtConfig({
modules: [
[BasicAuth, { enabled: true }],
],
runtimeConfig: {
basicAuth: {
productionDomains: [
'www.example.com',
],
pairs: {
foo: 'bar',
},
},
},
})
RuntimeConfig で設定した内容は、クライアントには渡りません。
ソースコード上に「ユーザー・パスワードの組み合わせ」 pairs
を記載したくない場合は、環境変数でセットしてください。
何も設定しなければ admin
: admin
になります。
productionDomains
は本番環境のドメイン(Basic認証をかけないドメイン)を指定します。
ドメインを endsWith
でチェックしているので example.com
は foo.example.com
にもマッチします。
また bar.example.com
は test--bar.example.com
にもマッチしますので、ご注意ください。
全体的に認証をかけたり外したりする場合は enabled
オプションで設定することができます。
(enabled
が false
の場合は serverMiddleware がアタッチされません)
Nuxt モジュールの作り方
基本的な Nuxt 3 モジュールの作り方は、公式ドキュメントに詳しくまとまっています。
Nuxt モジュールはプラグインと違い、ビルドのタイミングで Nuxt や Vue.js の挙動を操作することができます。
Basic 認証は serverMiddleware と同等の挙動を期待しています。
(Nitro の Plugin として構築することもできそうですが、今回は Nuxt の RuntimeConfig でオプションの設定を行うべく、Nuxt モジュールとして構築しました)
下準備
まずはローカル環境に、リポジトリを作成します
npx nuxi init -t module my-module
できあがった my-module
フォルダ内は次のようになっています
- playground
- src
src フォルダが開発するプラグインのソースコード用です。
playground フォルダは、開発中のモジュールの動作確認が行える(設定済みの)環境です。
playground 内で npm run dev
すれば Nuxt が起動し、モジュールがビルド時にプラグイン (src/runtime/plugin.ts
) をアタッチします。
ブラウザのコンソールに Plugin by my-module!
と表示されていることでプラグインが動作していることがわかります。
モジュール本体のソースコードは src/module.ts
です。
オプションを設定できるようにする
モジュールのオプションは playground/nuxt.config.ts
のように設定可能です。
(配列の2つ目の要素にオブジェクトで設定)
src/module.ts
の defineNuxtModule()
内で setup()
の第1引数として取得できます。
defaults
の内容が初期値としてマージされますので便利です。
module.ts
を作成する
メインの 今回は Plugin の利用はありません。
忘れずに src/runtime/plugin.ts
を削除しておきましょう。
今回は enabled
オプションのみとし、そのほかの設定は RuntimeConfig を使用します。
なお、モジュール作成に必要な機能は @nuxt/kit
から import することができます。
import { resolve } from 'path'
import { fileURLToPath } from 'url'
import { defineNuxtModule, addServerHandler } from '@nuxt/kit'
export default defineNuxtModule<ModuleOptions>({
meta: {
name: 'basic-auth',
configKey: 'basicAuth',
},
defaults: {
enabled: true,
},
setup (options, _nuxt) {
if (!options.enabled) {
return
}
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
addServerHandler({
middleware: true,
handler: resolve(runtimeDir, 'server/middleware/auth'),
})
},
})
serverMiddleware を作成する
src/runtime
以下に auth.ts
を作成します。
(今回は src/runtime/server/middleware/auth.ts
としました)
import { defineEventHandler } from 'h3'
import auth from 'basic-auth'
import { useRuntimeConfig } from '#imports'
export default defineEventHandler((event) => {
const {
pairs = { admin: 'admin' },
} = useRuntimeConfig().basicAuth || {}
const { name, pass } = auth(event.req) ?? {}
if (!name || !pass || !pairs[name] || pairs[name] !== pass) {
event.res.statusCode = 401
event.res.setHeader('WWW-Authenticate', `Basic realm="Authentication Required"`)
event.res.end('Unauthorized')
}
})
ヘッダーの情報は basic-auth
という npm パッケージを使用し取得しました。
利用者の RuntimeConfig は #imports
よりインポートする useRuntimeConfig()
で取得します。
(利用者の .nuxt/imports.d.ts
に記載されている node_modules/nuxt/dist/app
よりインポートされることになります)
※その他のオプションについてはこの記事では説明を省略します。
TypeScript の型情報を追記する
TypeScript の型を書いておくと、モジュールのビルド時に書き出してくれます。
declare module '@nuxt/schema' {
interface RuntimeConfig {
basicAuth: {
pairs?: Record<string, string>
}
}
}
export interface ModuleOptions {
enabled?: boolean
}
Netlify で使ってみる
上記のソースコードではすべての機能を記載していませんが、以上で一旦完成です。
Netlify は GitHub に push した内容で自動的にソースコードのビルドとサイトの公開が可能です。
設定によりメイン以外のブランチでも、コミットごとにステージング環境を用意してくれます。
(今回の記事では記載していませんが)用途としてはステージング環境(のみ)で動作してほしいモジュールですので、実際に Basic 認証がかかっているかを確認してみてください。
npm パッケージとして公開する
その他のオプションや、テストを記載したら、npm パッケージとして公開します。
(すでにビルド等の設定がなされているので煩わしい準備は不要です)
NPM への公開は npx np
コマンドが便利です。
(バージョン番号の管理から GitHub のリリースノートの下書き作成までやってくれます)
無事公開されたら npm i -D nuxt-basic-authentication-module
を、自分のプロジェクトの環境で実行します🎉
(本来の手順としては公開前に GitHub のリポジトリから直接インストールして動作確認となります)
おわりに
いちから調査しつつ構築しましたが、丸2日程度でできました。
なにより @nuxt/kit
が便利すぎます。
便利な機能を開発したら、再利用するためモジュールにしていきましょう。
そして、よろしければぜひ他の Nuxt ユーザーのために公開してください。
Nuxt のエコシステムが広がっていくことを期待しています。
Discussion