Site cover image
🏔️Cloudflare Zero Trustを越えてCORSリクエストを送る

Cloudflare Zero Trustを使えば簡単に認証を挟むことができるので、インターネットに公開したくないサーバー、例えば動作確認用のステージングサーバーなどを保護するのに便利です。

しかし、アプリケーションでCORSを使ってリクエストしている場合、 Zero Trustが障壁となってそのままではリクエストが失敗してしまいます。

Zero Trustを越えてCORSリクエストを通す方法は、予めZero Trustで認証したユーザーのクッキーを使う方法と、リクエスト時に認証トークンを送る方法の2つがありますが、この記事ではステージングでの動作確認を想定して前者を説明します。

CORSでPOSTリクエストを受けるには、まずサーバー側でプリフライトリクエストに対応する必要があります。

プリフライトリクエストとは、単純リクエストでない場合にリクエストの前に予め確認のためブラウザによってサーバーに送られるリクエストです。

単純リクエストについては下記を参照してください。

今回はJavaScriptでJSONデータをPOSTすることを想定しているので、単純リクエストに該当せず、プリフライトリクエストが必要になります。

プリフライトリクエストに対応するには、サーバーで OPTIONS メソッドを受け付け、適切なレスポンスヘッダーを応答する必要があります。

例として、今回次のような2つのサーバーがあると仮定します。

  • Webアプリケーション app.alpacat.com
  • APIサーバー api.alpacat.com

APIサーバー api.alpacat.com は Cloudflare Zero Trust によって守られており、Webアプリケーション app.alpacat.com からリクエストされます。

OPTIONS リクエストに対して、APIサーバーでは下記のレスポンスヘッダを付けて返します。

headers: {
  'Access-Control-Allow-Origin': 'https://app.alpacat.com',
  'Access-Control-Allow-Headers': '*',
  'Access-Control-Allow-Credentials' : 'true',
  'Access-Control-Allow-Methods': 'POST, OPTIONS',
  'Content-Type': 'application/json',
}

注意点として、今回のように認証情報を扱う場合( Access-Control-Allow-Credentialstrue の場合)、 Access-Control-Allow-Origin にワイルドカード * を使用することができません。

Cloudflare Zero TrustでCORSを設定します。

Settingsを開き Access-Control-Allow-Credentials を有効にします。

Access-Control-Allow-Origin には前述した通りワイルドカードは使えないため、具体的なオリジンを設定します。

Access-Control-Allow-MethodsAccess-Control-Allow-Headers は Allow all にチェックを入れておきます。

Image in a image block
Zero TrustでCORSを設定しよう

詳細は下記のドキュメントをご覧ください。

プリフライトリクエストだけでなく、実際にオペレーションを行うPOSTリクエストのレスポンスにも必要なヘッダーを追加する必要があります。

ここでは Access-Control-Allow-Origin ヘッダーと Access-Control-Allow-Credentials ヘッダーをプリフライトリクエストのレスポンスと同様に設定します。

headers: {
  'Access-Control-Allow-Origin': 'https://app.alpacat.com',
  'Access-Control-Allow-Credentials' : 'true',
  'Content-Type': 'application/json',
}

次にアプリケーションからJavaScriptのFetch APIを使ってCORSでPOSTリクエストを送る方法を見てみましょう。

JavaScriptのコードは下記のようになります。

fetch('https://api.alpacat.com/api/comments/new', {
  method: 'POST',
  mode: 'cors',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    content: 'Hello World!',
  }),
})

注意点としては mode: 'cors' にすることと、認証情報を送るために credentials: 'include' とすることくらいでしょうか。

実際にリクエストを送ってみて開発者ツールのコンソールにエラーが表示されなければ成功です。

もし何らかのエラーが発生した場合は、開発者ツールの「問題」タブに何を修正すれば良いのか詳しく表示されるので参照してみてください。

Image in a image block
問題タブで原因が詳しく説明される

以上です。この記事ではZero Trustを越えてCORSリクエストを通す方法として、予めZero Trustで認証したユーザーのクッキーを使う方法を説明しました。


💕
記事が参考になったら少額を寄付いただけると励みになります。
Thank you!
Thank you!
URLをコピーしました

コメントを送る

コメントはブログオーナーのみ閲覧できます