💭

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

2020/10/12に公開

※この内容は https://nazo.hatenablog.com/entry/nuxt-http-credentials と同一です

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

参考:nuxt.js は axios を捨てて ky になる様子

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

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

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

参考:CORS & Same Origin Policy 入門 | yamory Blog

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

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 指定があっても良かったのではないかと思います。

Discussion