nazolabo

Webエンジニアのnazoさんのブログです。お仕事募集中です。 https://nazo.dev/

nuxt/http で axios-module の credentials: true を再現する

https://github.com/nuxt/http は実質 https://github.com/nuxt-community/axios-module の後継に当たるもので、fetch APIをベースにした https://github.com/sindresorhus/ky を利用しています。

qiita.com

Migration Guides - Http Module を見てわかる通り、axios-module と比較しても名前が変わっただけのような作りになっており、置換だけでほぼ完全に移行することができますが、nuxt/http では credentials: true オプションが削除されています。今回はこれをどうしたらいいのかという話になります。

そもそも axios-module の credentials: true とは?

axios-module の credentials: true は、 XMLHttpRequest に対し withCredentials = true をデフォルトで設定するためのオプションです。クロスドメインCookie等の資格情報をXHR経由で渡す時に設定するものです。

yamory.io

withCredentials オプションは XHR 固有のもののため、fetch API には存在しません。代わりに credentials = 'omit' | 'same-origin' | 'include' というオプションが存在します。

  • omit : 同一ドメイン上でも資格情報が送られない
  • same-origin : 同一ドメイン上でのみ資格情報が送られる
  • include : 全てのドメインで資格情報が送られる

XHR での withCredentials = false が 'same-origin' で、 withCredentials = true が 'include' に該当します。(ただし polyfill を使うと omit に該当する XHR のオプションが存在しないために同一ドメイン上では資格情報の送信が行われます) なおサーバー側の Access-Control-Allow-Credentials 等は状況に応じて別途必要です。

nuxt/http で再現する

該当のオプションが存在しない nuxt/http で再現するには、デフォルト値を無理やり書き換える必要があります。プラグインで対応します。参考:Globally set options.Credentials · Issue #92 · nuxt/http · GitHub

export default ( { $http } ) => {
    $http._defaults.credentials = 'include'; 
}

TypeScriptではプロパティにアクセスができないので、型を破壊して強引にプロパティを変更します。

import { defineNuxtPlugin } from '@nuxtjs/composition-api';
import { Context } from '@nuxt/types/app';

export default defineNuxtPlugin(({ $http }: Context) => {
  ($http as any)._defaults.credentials = 'include';
});

まとめ

セキュリティ上の懸念点があるためにこのような対応が行われていると思いますので、強引に変えるのは良くないのではないかと思います。

nuxt/http では setToken() というメソッドが用意されており、 Authorization ヘッダをこちらでグローバルに指定することが可能です。こちらで資格情報を管理するのが良いのではないかと思いますが、axios-module と互換性があると言うのであれば credentials 指定があっても良かったのではないかと思います。