NuxtJS」カテゴリーアーカイブ

code on a screen

Nuxt3での簡易の認証フローを構築する

Nuxt3でアクセストークンを使った簡易な認証フローの構築をしてみます。

簡易な認証フローでは、route middlewareを使います。route middlewareはNuxt2にも同様にあった仕組みです。サーバーサイド(SSRサーバ初回アクセス時)、クライアントサイドで動作し、ページ遷移時に認証などのフィルタを挟んだりすることができます。ページコンポーネントに以下のように記述することで、ミドルウェアを宣言的に適用することができます。

参照:ミドルウェアディレクトリ 

なお、server/middlewareという仕組みもありますが、これはサーバーリクエストごとに動作するミドルウェアです。ドキュメントにもあるように、何らかのチェックやヘッダの操作、ロギングなどに使用する用途のようです。expressでrouteをマウントしても呼ばれます。Nuxt3の内部で使われているh3 httpフレームワークのミドルウェアとして登録されます。

https://v3.nuxtjs.org/guide/features/server-routes#server-middleware

そのため今回は、route middlewareの仕組みを使って構築してみます。

テスト環境

  • nuxt@3.0.0-rc.8

今回のフロー

以下のような構成にしてみます。nuxt-auth moduleもcookieを使った同様の機構があります。

  • トークンはcookieに保存、ログイン時にcookieに書き込む。クライアント側でもread/writeするのでHttpOnly属性はなし。
  • SSR時は、cookieからトークンを読み出して使う。
  • route middlewareでは、cookieから値を読み出しログイン済みかどうかをチェックする。

この他、以下の仕組みを使うので補足します。

route middleware

route middlewareですが、middlewareディレクトリに配置すると自動でインポートされます。.globalというサフィックスをつけることで、全体に対して適用することができます。

  • middleware/auth.ts
    • definePageMetaでページコンポーネントに対してミドルウェアを適用する
  • middleware/auth.global.ts
    • 全体に渡ってミドルウェアが適用される

useCookie

useCookieというcomposableライブラリを使用します。useCookieは、サーバサイドとクライアントサイドで使えます。useCookieによる返り値に対しvalueを書き込みすることで、裏でNuxtが上手いこと処理をしてくれます(具体的には後述の通り)。

これにより、SSR時でもアクセストークンを取得し、フェッチリクエスト時にヘッダにトークンを埋め込むことができるようにします。

クライアントサイドの動作

クライアントサイドでは、document.cookieより指定したcookieを取得します。そのため、HttpOnlyが指定されたcookieは使えません。useCookieにより得たcookieはrefオブジェクトとなっており、valueに値を書き込むことでdocument.cookieにシンクされます。

サーバサイドの動作

サーバサイドでは、フックのタイミングでレスポンスヘッダにcookieが書き込まれます。

route middlewareを使った例

では、実際に構築してみます。フローを確認するためのサンプルなので、エラーチェックやその他バリデーションなど厳格さは欠いていますことご容赦ください。

server/api/login.ts

今回は、トークンを返すだけの簡易な処理としています。

server/api/posts.ts

ログイン後に何らかの投稿記事一覧を返す処理とします。リクエストヘッダから、Authorizationヘッダを読みトークンを確認します。トークンがあれば、ひとまず記事一覧を返すとします。

middleware/auth.global.ts

useCookieを使っています。ログインに成功すると、cookieに値を書き込みます。同時にdocument.cookieにも書き込まれます。

pages/login.vue

pages/dashboard.vue

以下のような感じで動きます。

 参考リンク

code on a screen

Nuxt3のruntimeConfigで環境変数を設定する

はじめに

nuxt3には、実行時に設定値をロードするための仕組みとしてruntimeConfigというものがある。コンポーネント内からはuseRuntimeConfigや$configで値にアクセスすることができる。サーバサイド(private)、クライアントサイド(frontend)で公開範囲を区別することもできる。本記事では、runtimeConfigの設定方法と使い方についてざっと整理する。

privateとpublic configuration

runtimeConfigの下に定義されているプロパティはprivate、publicやappブロックに定義された値はfrontendに公開される。

.envからの定義を渡す

nuxt.config.tsのruntimeConfigに定義することで利用できるが、よくやる方法として、.envに定義した値をruntimeConfigにセットするというアプローチがあるだろう。以下のような感じだ。

この方法でも問題ないが、毎回.envの値をruntimeConfigにセットしない方法もある。次に、.envの特定の値を動的にruntimeConfigに反映する例を見てみる。

.envからの定義を動的に渡す

.envに特定のプリフィックスNUXT_またはNITRO_をつけた値は、runtimeConfigに定義されていればruntimeConfigに動的に設定されるようになっている。なお、この際runtimeConfigのjson構造の階層と合わせてやる必要がある。具体的な例を見てみる。

この定義を動的に読み込むためのnuxt.config.tsは以下のようになる。

コンポーネントでは以下のようにアクセスできるだろう。

apiKeyはprivateなので見えない。frontendConfigはpublicのためフロントエンドで見える。ssrのレスポンスを見るとwindow.__NUXT__の定義のruntimeConfigプロパティとし見えるのが分かる。

NITRO_とNUXT_の両方が定義されている場合

NITRO_の優先順位が高くなっているので、両方定義されている場合はNITRO_の定義が勝つ。

独自のprefixを指定したい

NUXT_でなく、MYAPP_のような独自のprefixをつけたい場合は、以下のようにnitroのenvPrefixを書き換える。

参考リンク

 

code on a screen

Nuxt3でtailwindcssを使う

はじめに

nuxt3でtailwindcss(bootstrapのようなcssフレームワーク)を使えるようにします。nuxt3は、本記事掲載時点ではバージョンrc4となっており正式リリースはされてない状況ですが、少しずつ触っていきたいと思います。公式サイトのロードマップを見るとmidsummerとなっているのでもうすぐリリースでは!?と楽しみにしてます。

nuxtでは、tailwindcss向けのモジュールが提供されているので、モジュールを使うことで簡単に導入することができます。では、実際に入れて試してみたいと思います。

https://tailwindcss.nuxtjs.org/

まずはNuxt3を入れる

公式の通りです。

@nuxtjs/tailwindcssの導入

続いてtailwindcssを入れます。@nuxtjs/tailwindcssモジュールを入れます。

@nuxtjs/tailwindcssは、すでにnuxt3対応されています。続いて、nuxt.config.tsにモジュールを使用する指定を追加します。

これで基本的には動作するようになります。

tailwindcssのconfiguration

@nuxtjs/tailwindcssではモジュール起動時にデフォルトの設定を適用するようになっているため、設定ファイルを用意しなくともすぐに使えるようになっています。tailwindcssでは、通常tailwind.config.jsというconfigurationファイルで設定を記述するようになっています。@nuxtjs/tailwindcssでは、configurationの記述場所としてtailwind.config.jsを含めて3つの方法が用意されています。

  1. tailwind.config.js
  2. nuxt.config.ts
  3. nuxt hook

参考:https://tailwindcss.nuxtjs.org/tailwind/config

今回は、tailwindcssの通常である1の方法で設定を上書きしてみます。

設定を変更したい場合は、設定ファイルをプロジェクトトップに置きます。(なお、この場所は変更可能となっているようです)。以下のコマンドでtailwind.config.jsの雛形が生成されます。

今回は、tailwindcssのcss定義にtw-というプリフィックスをつけるよう設定してみましょう。ここでは、prefixのみを指定していますが、本設定は@nuxtjs/tailwindcssが用意するデフォルト定義にマージされます。マージ動作については、上記のconfig説明ページに書かれていますが、defuライブラリが使われています。

これで、tailwindcssを使う準備ができました。

動かしてみる

では、実際に使ってみましょう。サンプルアプリは以下の構造です。

app.vue

pagesのファイルを表示するようにしています。

pages/index.vue

ただのHello Worldを表示するだけのページです。tw-でプリフィックスをつけてます。

npm run devすると以下のようなページが表示され、cssが効いていることを確認できます。

また、開発モードでnuxi devで動かしている場合は、tailwind viewerも使えます。カタログを見るような感じでコードの記述が捗ります。

http://localhost:3000/_tailwind/

いい感じに動いてそうですね。

参考リンク

crop faceless developer working on software code on laptop

Nuxt3をさわってみる

Nuxt3はbeta版になっている、Nuxt3の雰囲気をつかむためインストールから起動するところまでやってみる。

インストール

nuxiという新しいCLIを使う。

nuxiについて、プロジェクトのトップでinfoコマンドを実行してみる。

ディレクトリ構造

initした直後は以下の感じ。Nuxt2までのようなlayoutsやpagesのようなディレクトリがなく、プロジェクト作成直後はとてもすっきりしている。

ドキュメントを見ると、今までのようなlayoutsやpagesといったディレクトリは、Nuxt3でも有効であることが分かる。これらは、アプリの特性に合わせて作成すればよいのだと思う。なお、ディレクトリについては、pluginsディレクトリ下のプラグインファイルが自動で読み込まれるなど新しい点もあるので注意したい。

参考リンク

アプリ起動

この状態でrun devするとWelcomeビューが表示される。 

httpsオプションで自己署名証明書を使ってhttpsモードで起動ができる。Nuxt2では、nuxt.configのserverオプションで指定していたと思うけれど、この辺りとても簡単になっている。

Welcomeビューを変更するには、app.vueを編集するか、pages/index.vueのような新たなビューを作る。

srcDirの変更

公式ドキュメントにあるようなclientの下にアプリリソースを配置する構成にしてみる。ディレクトリを作成し、nuxt.configのsrcDirにclientリソースを格納するディレクトリを指定、そして今ままでのようなlayoutsやpagesにビューを作成する。

上記の変更を加え、改めてrun devしてみると以下のように作成したビューが表示されることを確認できる。

 

参考リンク

BoskampiによるPixabayからの画像

NuxtJS+socketioで認証フィルタをはさむ(passport)

NuxtJSでサーバ側はexpress、websocketを使うのにsocket.ioを使っていて、ユーザー認証をpassportで行なう場合の覚書き。

今回試すこと

axiosを使ってサーバAPIでログインし、その後socket.ioでwebsocketに接続する。やりたいことは、サーバAPIで開始したセッションをsocket.ioで引き継ぎ利用することである。

これには、socket.ioのミドルウェアを使って開始済みのセッションを読み込めば、socket.ioのリクエストでセッションを扱える。気をつける点は、socket.ioのミドルウェア関数インターフェースがexpressのそれと異なっているので、正しく情報を引き継げるようミドルウェアをつないでやることである。具体的には、socket.ioのドキュメントにもあるとおり以下のようにすればよい。

socket.ioのロード

今回は、NuxtJSのmoduleのlistenフックを使ってsocket.ioサーバをnuxtのhttpサーバ に統合する。serverMiddlewareで、/apiにexpressのappをマウントする。また、Nuxtのlistenフックを使ってsocket.ioサーバを統合するための設定をmodulesに定義する。

サーバ側

今回は動作検証のため、セッションはメモリストアを使っている。socket.ioとセッションストアを共有するため、共通の定義を使うようにしている。

server/index.js

server/session.js

server/io.js

クライアント側

クライアント側は、ログインしてセッション確認するだけのためのインターフェースにする。以下のような感じ。

ログインしていない状態の時。

ログインしてsocket.ioにつながった時。

Viewテンプレートはveutifyを使う。

pages/index.vue

NuxtJSは、Universalモードで動かしているのでSSRを行なう。sessionは、asyncDataフックを使ってコンポーネントのdataに統合する。

検証用プログラムは以下

https://github.com/moritetu/nuxt-with-socket.io-passport

参考リンク