update.はじめに「とりあえずなんとかする方法は知っているけど、なんでそれでいいのかわからない」という疑問を解消していきます。今回はCORS編です。長くなるので、時間がない方は先に結論を見てください。問題となるエラーについてAPIサーバーとWebサーバーをそれぞれ別ポートで立てている時、以下のようなエラーが出る場合があります。これは、開発環境でAngular(localhost:4200)からDjango(localhost:8000)へAPIリクエストを投げた時に起きるエラーです。policyによって拒否されました」と怒られます。このエラーの意味するところから理解し、対策・解決方法を探っていきます。Cross-Originオリジンオリジンとは、「プロトコル」+「ホスト」+「ポート番号」の組み合わせのことです。8000ポート番号が異なるので、別のオリジンとなります。Cross-Originでは、なぜ別のオリジン間(Cross-Origin)の通信が問題になるのでしょうか。forgeries)が考えられるからです。CSRFは以下の手順で実行されます。不正なアクセスを行うスクリプトを仕込んだページを用意するユーザーにアクセスさせ、攻撃用ページを踏ませるアクセスしたユーザーから不正なアクセスが行われる不正なアクセス自体はユーザーから送信されるので攻撃者は発覚しない、という手法です。この攻撃方法は、あるドメインから読み込まれたページから、別のドメインへのアクセスが許可されている脆弱性をついています。そのため、通常はオリジン間のHTTPリクエストは制限されます。今回のエラーも、localhost:4200から読み込まれたページで実行される、localhost:8000へのHTTPリクエストが制限に引っかかったため生じました。次に、DjangoのCSRF対策について確認します。入っていない、またはトークンが違う場合、403(Forbidden)エラーを返すとなっています。CORS次に、対策・解決方法を考えていきます。オリジン間の制限を変更することで、別オリジン間のHTTPリクエストを許可すれば良いはずです。Sharing)と言います。設定可能なヘッダーについては公式ぺージを参考にしてください。基本的にデータを取得される側(APIサーバー)でアクセス許可設定を行います。「localhost:4200はAccess-Control-Allow-Originで許可されていません」と怒られています。レスポンスに「Access-Control-Allow-Origin」というヘッダーを追加します。後ほど別の方法は紹介しますが、テストのためにDjangoのViewを以下のように変更します。responseこれでレスポンスが正常に返ってきます。レスポンスヘッダーは以下のようになっています。POST、DELETEなどのメソッドだとうまくいかないケースがあります。エラーとしては以下のようになります。見知らぬ単語「Preflight」が出てきました。次はこのエラーに取り掛かりましょう。Preflight特定のメソッドや、特定のヘッダーがリクエストに入っていると、実際のリクエストを投げる前に、別ドメインの送信相手に安全確認をとる仕様となっています。この事前リクエストをPreflightリクエストと言います。別ドメインからのPreflightリクエストに対し、APIサーバーがどのようなリクエストならアクセスを許可するかを返し、そのレスポンスが返ってきてから実際のリクエストを投げます。実際のリクエストのContent-Typeヘッダーが許可されていないことからエラーになっているようです。先ほど確認したDjangoのCSRF対策と合わせて考えると、Preflightメソッドに対してレスポンスを返すクッキーの「csrftoken」をヘッダーに追加することで解決するはずです。これもまた別の方法がありますが、テストのためにViewを以下のように変更します。responseまた、Angular側で、ヘッダーにトークンを追加します。}}また、app.module.tsも変更します。true}を追加します。これでPOSTリクエストも成功します。django-cors-headers以上で別オリジンからのリクエストを正常に処理できるようになりました。Djangoには便利なライブラリがあります。django-cors-headersです。今までは確認のためにviewで返すリクエストに直接ヘッダーを追加していましたが、django-cors-headersを使用し、設定をすれば勝手にヘッダーを追加してくれます。Trueこれだけです。そのほかにも設定があるので、状況によって追加・変更を行います。結論django-cors-headersを使うまたはレスポンスにヘッダーを追加するAngularでクッキーに入っている「csrftoken」を「X-CSRFToken」ヘッダーに追加HttpClientのメソッドオプションの「withCredentials」をtrueにするHttpClientXsrfModule.withOptionsを設定する以上で解決するはずです。自分はAngular側の設定で時間を溶かしてしまいました...。何かあればコメント・指摘等お願いします。