web-dev-qa-db-ja.com

file://でローカルにロードされたモバイルWebViewからのCORSCookie資格情報

我慢してください、これは少し説明が必要です。

ハイブリッドモバイルウェブアプリの構築を手伝っています。メインのコードベースはHTML5とJavaScriptで、ネイティブのモバイルWebビュー(Phonegap)にラップされます。

機能の一部では、アプリがクライアントの1つによって制御されるWebサービスに情報を投稿する必要があります。他の人が使用しているため、このWebサービスを変更する余地はほとんどありません。 HTTP POSTを使用してJSONを送信し、サーバーから応答を受信します。この応答の一部は、サーバーとのセッションを管理するJSESSIONIDCookieです。最初のinitSession()呼び出しの後、すべての(AJAX)リクエストでJSESSIONIDCookieを送信する必要があります。

モバイルデバイスにデプロイすると、WebアプリはネイティブWebビューにラップされ、_file:///path/to/app/index.html_を参照してWebアプリを起動します。

最初に試したのは、CORSを許可するために応答ヘッダーに_Access-Control-Allow-Origin: *_を設定するようにクライアントに依頼することでした。次に、サーバーに投稿してみました。

_$.ajax({
  url: 'http://thirdparty.com/ws',
  data: data,
  type: "POST",
  dataType: "JSON",
  success: successCallback,
  error: failedCallback
});
_

リクエストを監視すると、Cookieが含まれていないことが明らかになりました。詳細に調べると、 ユーザー資格情報を処理するためのCORS仕様の特別なセクション があります。これにはセッションCookieが含まれます。そこで、AJAX呼び出しを変更して、これを含めました。

_$.ajax({
  url: 'http://thirdparty.com/ws',
  data: data,
  type: "POST",
  dataType: "JSON",
  success: successCallback,
  error: failedCallback,
  xhrFields { withCredentials: true }
});
_

別のエラー、今回はブラウザから。さらに読むと、次のようになりました。

サードパーティのサーバーが_Access-Control-Allow-Credentials: true_ヘッダーで応答しなかった場合、応答は無視され、Webコンテンツで利用できなくなります。

重要な注意:認証されたリクエストに応答する場合、サーバーは_Access-Control-Allow-Origin_ヘッダーでドメインを指定する必要があり、ワイルドカードを使用することはできません。

したがって、サーバーのヘッダーを変更して、_Access-Control-Allow-Credentials: true_と_Access-Control-Allow-Origin_をオリジンに含める必要があります。

ここでようやく私の問題が発生します: file://プロトコルを使用してWebページをロードする場合 、Webビューから送信されるOriginリクエストヘッダーはnullに設定されます。したがって、サーバーで解析できないため、サーバーは_Access-Control-Allow-Origin_に設定できません。ただし、サーバーが_Access-Control-Allow-Origin_を_*_以外に設定できない場合、Cookieを含む資格情報を送信することはできません。

だから私は立ち往生しています。何をすべきか? ここに同様の質問が投稿されています しかし、提案された回答がよくわかりません。どんな助けでも大歓迎です!

30
Tom Spencer

この質問は古いと思いますが、とにかく投げ込むと思いました。 CORSリクエストの場合、ブラウザはそれらをプリフライトします。これが意味するのは、使用している$.ajax()メソッドに関係なく、OPTIONSリクエストがサーバーに送信されるということです。

このプリフライトされたOPTIONSリクエストが実際に行っていることは、次のことです。

「ねえ、foreign-server-from-some-other-domain、私はあなたに単純でない要求を送りたいです(単純な要求はプリフライトされません)。私の単純でない要求はこれらの種類のヘッダーとコンテンツタイプを持ち、など。これで問題ないかどうか教えていただけますか?」

次に、サーバーは実行することをすべて実行し(おそらく、構成またはデータベースをチェックします)、許容されるオリジン、許容されるヘッダー、および/または許容されるメソッドで応答します。

最後に、そのプリフライトOPTIONSリクエストが、実際の$.ajax()メソッドの実行を許可する応答を受信した場合は実行されます。

CORSはJSONPと同じではありません。

とはいえ、withCredentialsの飛行前の成功には、応答にAccess-Control-Allow-Credentialsヘッダー(質問に記載されている)を含める必要があります。これは、Access-Control-Allow-OriginsおよびAccess-Control-Allow-Methodsの値に追加されます。 、目的のリクエストのファセットを含める必要があります。

たとえば、Origin http://foo-domain.comからヘッダーPOSTからhttp://bar-domain.comへのCORSsomevalueリクエストを行う場合、プリフライトOPTIONSリクエストは送信されます。実際のPOSTリクエストがhttp://bar-domain.comに対して行われるためには、OPTIONSリクエストはAccess-Control-Allow-Originsを含むhttp://foo-domain.com値を持つ応答を受信する必要があります。これは、オリジン名自体または*である可能性があります。応答には、POSTを含むAccess-Control-Allow-Methods値も必要です。これは*の場合もあります。最後に、somevalueヘッダーを許可する場合、応答にはsomevalueヘッダーキーまたはAccess-Control-Allow-Headersを含む*値が含まれている必要があります。

サークルバックするには-サーバーを制御できない場合、またはサーバーにCORSリクエストを許可する方法がない場合は、常にJSONPまたはいくつかのurlEncodedデータ型を使用するか、カスタムヘッダーなしで単純なリクエストを行うことができます。 GETHEAD、および完全なPOSTリクエストは通常​​、単純なリクエストです。

7
J.Wells

ハイブリッドアプリケーションを作成している場合は、cordovaを使用していると思います。その場合、CORSは必要ありません。アクセスするドメインをホワイトリストに登録するだけです。

http://docs.phonegap.com/en/3.0.0/guide_appdev_whitelist_index.md.html

私の提案は、サーバー側でACCESS-CONTROL-ALLOW-Originnullに設定します

はい、この質問は少し気になります。

CORS仕様 に関して、nullは、file://スキームからのCORSリクエストの状況に対応できます。

そして、その仕様に関する実際的な推奨事項は、それを Origin-list-or-null として設定することです。これは、スペースで区切られた起点のリストか、単に「null」(ちなみに、文字列%x6E %x75 %x6C %x6C)です。 Origin-list-or-nullの定義から、文字通りnull 16進エンコードされます)

最後に、スキーム*からのすべてのリクエストが有効であるため、ACCESS-CONTROL-ALLOW-Originnullに設定した場合、それはfile://に等しいのではないでしょうか(つまり、すべてのハイブリッドアプリがあなたのuriを知っていればエンドポイントにアクセスできます)?

Access-Control-Allow-Credentials: trueを考えると、サーバー上で認証メカニズム全体が機能していると思います。正しい認証なしでそれらのリクエストをフィルタリングする必要があります

それが役立つことを願っています

1
Ace

Www.5app.co.ukを見てみてください。 XHR呼び出しの使用を完全に回避し、データ接続が行き来するときにモバイルで確実に機能します。次に、ゲートウェイはクライアントとインターフェイスします。

0
Tim King

JsonPリクエストを使用します。 JsonPリクエストを使用すると、クロスドメインリクエストを実行できます。 ここ は一例です。

0
ksivamuthu

たとえば、PHP側では、次のように設定する必要があります。

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With, Set-Cookie, Cookie, Bearer');
header('Access-Control-Allow-Credentials: true');
// header('Cookie: PHPSESSID='.$_COOKIE['PHPSESSID']);
0
Onimo