jQuery
Ajax
AngularJS
htaccess
CORS

CORSリクエストでクレデンシャル(≒クッキー)を必要とする場合の注意点

More than 1 year has passed since last update.

クレデンシャルの送信

クロスオリジンのAJAXリクエストでクレデンシャル(クッキーの送信またはBASIC認証)を必要とする場合は、それを許可するオプションをフロント側Javascriptで付けておく必要があります。デフォルトではCORSリクエストでクッキーは送信されませんし、BASIC認証は送れません。

Fetch API の場合

fetch(url, {
  mode: 'cors', //クロスオリジンリクエストをするのでCORSモードにする
  credentials: 'include' //クレデンシャルを含める指定
})

jQueryの場合

$.ajax({
  url: "http://example.jp/api/user",
  xhrFields: {
    withCredentials: true
  }
}).success(function(res){
  console.log(res);
})

毎回付けるのが面倒なら↓こうしておいてもよいです。

$.ajaxSetup({xhrFields:{withCredentials:true}});

AngularJS(1.x系)の場合

AngularJSの場合はこんな感じか。

yourapp.config(function($httpProvider) {
  $httpProvider.defaults.withCredentials = true;
});

XMLHttpRequest を直接使う場合

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

Access-Control-Allow-Origin: * は駄目

クレデンシャルを必要とするリクエストの場合、Access-Control-Allow-Originにワイルドカードは使えまえん。キチンと許可オリジンを指定しましょう。

そうは言ってもワイルドカード的に受け付けたい場合はあるので手軽に.htaccessで何とかする設定メモ。これは送られてきたOriginを許可オリジンとしてオウム返しする設定です。

.htaccess
RewriteCond %{HTTP:Origin} (.+)
RewriteRule . - [E=CORS_ORIGIN:%1]
Header set Access-Control-Allow-Origin %{CORS_ORIGIN}e env=CORS_ORIGIN

CORSアクセスを許可するOriginを限定したいなら↓こんな風に書いてやればOK

.htaccess
RewriteCond %{HTTP:Origin} (https?://([a-zA-Z0-9\-\.]+\.)?(example\.com|example\.jp)(:[0-9]+)?)$
RewriteRule . - [E=CORS_ORIGIN:%1]
Header set Access-Control-Allow-Origin %{CORS_ORIGIN}e env=CORS_ORIGIN

Access-Control-Allow-Credentials: true も付けましょう

クレデンシャルを必要とする場合はこのヘッダがないとブラウザはレスポンスを捨ててしまうのでセットで付けておきましょう。

.htaccess
Header set Access-Control-Allow-Credentials true

その他基本のキ

よく使うヘッダのコピペ用設定。アプリのフレームワークによっては X-Csrftoken ヘッダも通しておくなど。

ベタ書き版

.htaccess
Header set Access-Control-Allow-Methods "GET, PUT, POST, DELETE, HEAD, OPTIONS"
Header set Access-Control-Allow-Headers "X-Requested-With, Origin, X-Csrftoken, Content-Type, Accept"

クライアントのリクエストに合わせて許可する版

httpd.conf
# CORS対応

## Originの許可(オウム返し)
RewriteCond %{HTTP:Origin} (https?://([a-z0-9\-\.]+\.)?example\.com)$
RewriteRule . - [E=CORS_ORIGIN:%1]
Header set Access-Control-Allow-Origin %{CORS_ORIGIN}e env=CORS_ORIGIN

## リクエストメソッドの利用許可(オウム返し)
RewriteCond %{ENV:CORS_ORIGIN} ^http
RewriteCond %{HTTP:Access-Control-Request-Method} ^([A-Z]+)$
RewriteRule . - [E=CORS_METHOD:%1,E=CORS_PREFLIGHT:1]
Header set Access-Control-Allow-Methods "GET, POST, HEAD, OPTIONS, %{CORS_METHOD}e" env=CORS_METHOD

## リクエストヘッダの利用許可(オウム返し)
RewriteCond %{ENV:CORS_ORIGIN} ^http
RewriteCond %{HTTP:Access-Control-Request-Headers} "^([a-zA-Z0-9-]+(, ?[a-zA-Z0-9-]+)*)$"
RewriteRule . - [E=CORS_HEADERS:%1,E=CORS_PREFLIGHT:1]
Header set Access-Control-Allow-Headers "%{CORS_HEADERS}e" env=CORS_HEADERS

## レスポンスヘッダの利用許可
# Header set Access-Control-Expose-Headers "* or X-Hoge, X-Fuga" env=CORS_ORIGIN

## クレデンシャルの送信許可(クッキー,Authorizationヘッダ)
# Header set Access-Control-Allow-Credentials true env=CORS_ORIGIN

## CORS許可のキャッシュ(プリフライトリクエストを暫く投げない許可)
Header set Access-Control-Max-Age "3600" env=CORS_PREFLIGHT