CORS を設定して別サイトのセッションを取得する
Web アプリケーションを開発していて、別ドメインのログイン状態を取得する際に CORS の仕組みについて勉強することができたので、設定ポイントをまとめておきます。
CORS とは
Cross-Origin Resource Sharing の頭文字をとった略語です。
通常、ブラウザでは異なるサイトへのリソースへのアクセスに制限をかけて、CSRF などの攻撃を防いでいます。 CORS とは、この制限に対し、適切な設定を行うことで異なるサイトのリソースを共有できるようにするものです。
オリジンとは
ブラウザは、同じサイトか異なるサイトかについて、オリジン (Origin) という単位で区別します。
同一スキーム、同一ホストおよび同一ポートのものが同一オリジン (Same-Origin) となります。
同じホストでも、スキーム (http/https) やポートが違っていれば異なるオリジンとなります。
以下は https://www.example.com
までが同じなので、同じオリジンとなります。
https://www.example.com/foo/
https://www.example.com/bar/
同じホスト名であっても以下はスキーム (http/https) が違うので、これらは異なるオリジンです。
http://www.example.com/foo/
https://www.example.com/foo/
同じオリジンであれば、とくに制限なくリソースの共有ができます。
異なるオリジンの場合は、CORS の適切な設定が必要となります。
やりたいこと
ブラウザでは事前にサイト A にログイン。サイト A のセッションクッキーを持ちます。
サイト B のページにおいて、Ajax によりサイト A のログイン状態を取得し、
ログインしていればログインユーザー名などを表示します。
それぞれのオリジンを以下とします。
サイト名 | URL |
---|---|
サイト A | https://site-a.example.com/ |
サイト B | https://site-b.example.com/ |
HTTP ヘッダーの設定
Access-Control-Allow-Origin
サイト A 側では、サイト B からのアクセスを許可するために、以下のヘッダーを出力するようにします。
Access-Control-Allow-Origin: https://site-b.example.com/
画像ファイルなどの通常のリソースは、この Access-Control-Allow-Origin ヘッダーによる Origin の許可ができていれば共有できます。
Access-Control-Allow-Credential
しかしながら、サイト間の Ajax呼び出しで HTTPクッキーや HTTP認証といった 資格情報 は、デフォルトでは送信されません。
資格情報の取得を許可するには、 以下のように Access-Control-Allow-Credential ヘッダーを入れる必要があります。
Access-Control-Allow-Credential: true
それから、資格情報の場合は、Access-Control-Allow-Origin: では * (アスタリスク)によるワイルドカードは使用できません。明示的に Origin を指定する必要があります。
具体的な設定だと、
Apache なら、
Header set Access-Control-Allow-Origin https://site-b.example.com/
Header set Access-Control-Allow-Credentials true
nginx なら、こんな感じです。
add_header Access-Control-Allow-Origin "https://site-b.example.com/";
add_header Access-Control-Allow-Credentials true;
セッションクッキーの設定
サイト A 側で発行するセッションクッキーの設定にも気を配る必要があります。
セキュアクッキーであること、 SameSite が None であることが必要です。
PHPの場合は、 session_set_cookie_params でセッションクッキーの設定を行ってから session_start します。
最近の PHP(7.3.0以上)であれば、SameSite の指定がオプションパラメータの配列で指定できます。
session_set_cookie_params([
'lifetime' => $maxlifetime,
'domain' => $_SERVER['HTTP_HOST'],
'path' => '/',
'httponly' => $httponly,
'secure' => true, // セキュアクッキーであること
'samesite' => 'None' // SameSite が Noneであること
]);
session_start();
7.3.0 未満の古い PHP の場合、ドメイン・パスの後ろにセミコロンで区切って、SameSite の指定を直接入れてやります。
session_set_cookie_params($maxlifetime, '/; SameSite=None', '', true);
session_start();
Ajaxの呼び出し
サイト B からサイト A の Ajax呼び出しを行うときにも withCredentials の設定が必要です。
サイト B の JavaScript
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://site-a.example.com/login_user', true);
xhr.withCredentials = true;
xhr.send(null);
jQuery ならこんな感じ。
$.ajax({
url: "https://site-a.example.com/login_user",
xhrFields: {
withCredentials: true
}
}).success(function(res){
// 処理
})
仕組みが理解できても、設定ポイントがいくつかあるので、漏れのないように設定するのがたいへんです。
本記事を参考にチェックしてみてください。
参考
Author And Source
この問題について(CORS を設定して別サイトのセッションを取得する), 我々は、より多くの情報をここで見つけました https://qiita.com/tanaka-qtaro/items/deda59b2ae6c1270ab5f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .