Help us understand the problem. What is going on with this article?

クロスドメインのAjax通信でセッションを維持する

More than 3 years have passed since last update.

xxxx.net と api.xxxx.net の間でアカウント認証を行い、セッションIDをクッキーで書き込んでもらう際にハマった話。

xxxx.net のログインページのフォームにアカウント名とパスワードを入力し、api.xxxx.net のWebAPIにAjaxを使用して送信する。

HKUser.js
HKUser.signin = function(form, callback)
{
    var postdata = form.serialize();
    $.ajax({
        type:"POST",
        async:true,
        dataType:"json",
        cache:false,
        url:"https://api.xxxx.net/1/user/signin",
        data:postdata,
        success:function(data) {
            .....
        },
        error:function(error) {
            .....
        }
    });
}

クロスドメインでAjax通信を行う際は、応答側(この場合、api.xxxx.net側)で「Access-Control-Allow-Origin」を設定する必要がある。

Access-Control-Allow-Originには、通信するプロトコルとドメインを記述する。

header("Access-Control-Allow-Origin: https://xxxx.net");
header("Content-Length: {$len}");
header("Content-Type: application/json");
echo $out;

さぁ、これでクロスドメインでやりとりすることができるようになった。
アカウント認証後、セッションクッキーを受信した後、セッションデータを受け取ろうとしたら、送信側のセッションIDと受信しているセッションIDの値が違う。
xxxx.net 側で作成されたセッションIDになっている。api.xxxx.net で発行されたセッションIDがクッキーに書き込まれていない。

クロスドメインでクッキーをやりとりするには、以下の設定が必要です。
XMLHttpRequest のwithCredential をtrueに設定して下さい。

HKUser.js
HKUser.signin = function(form, callback)
{
    var postdata = form.serialize();
    $.ajax({
        type:"POST",
        async:true,
        dataType:"json",
        cache:false,
        url:"https://api.xxxx.net/1/user/signin",
        data:postdata,
        xhrFields: {
            withCredentials: true
        },
        success:function(data) {
            .....
        },
        error:function(error) {
            .....
        }
    });
}

XMLHttpRequest.withCredentials

XMLHttpRequest.withCredentialsプロパティは、Cookie、承認ヘッダー、TLSクライアント証明書などの資格情報を使用してクロスサイトアクセス制御要求を行う必要があるかどうかを示すブール値です。
WithCredentialsを設定しても、同じサイトのリクエストには影響しません。
加えて、このフラグは、クッキーがレスポンスで無視される時期を示すためにも使用されます。 デフォルトはfalseです。
別のドメインのXMLHttpRequestは、要求を行う前にwithCredentialsがtrueに設定されていない限り、独自のドメインのCookie値を設定できません。
withCredentialsをtrueに設定して取得したサードパーティのCookieは、同じ発信元ポリシーを引き続き遵守するため、要求元のスクリプトがdocument.cookieまたは応答ヘッダーからアクセスすることはできません。

また、サーバ側(api.xxxx.net)の応答に以下のヘッダが必要です。
Access-Control-Allow-Credentialsを、trueに設定してください
この場合、Access-Control-Allow-Origin でワイルドカードの使用が許可されません。

header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Origin: https://xxxx.net");
header("Content-Length: {$len}");
header("Content-Type: application/json");
echo $out;

Access-Control-Allow-Credentials

Access-Control-Allow-Credentialsレスポンスヘッダーは、要求に対する応答をページに公開できるかどうかを示します。 真の値が返されたときに公開されます。
証明書は、Cookie、承認ヘッダー、またはTLSクライアント証明書です。
プリフライトリクエストに対する応答の一部として使用される場合、実際の要求が資格情報を使用して行われるかどうかを示します。
単純なGETリクエストはプリフライトされていないので、資格情報を持つリソースに対してリクエストが行われた場合、このヘッダがリソースと共に返されないと、レスポンスはブラウザによって無視され、Webコンテンツに返されません。
Access-Control-Allow-Credentialsヘッダーは、XMLHttpRequest.withCredentialsプロパティまたはFetch APIのRequest()コンストラクターの資格情報オプションと共に使用します。
資格情報を持つCORS要求が成功するためには、資格情報を両方の側(Access-Control-Allow-CredentialsヘッダーとXHRまたはフェッチ要求)に設定する必要があります。

これでセッションIDをSet-Cookieヘッダで送信すれば、ブラウザに保存されているはずです。

hilucky
GCP, AWS, PHP, node, Python, RaspberryPi, ESP32, ESP8266, Keras, Tensorflow...
https://hilucky.io
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした