web-dev-qa-db-ja.com

HTTPヘッダーのSet-Cookieは、AngularJSでは無視されます

私は、クライアント側のAngularJSとサーバー側の私のAPI(Tomcat + JerseyのWS)用のJavaに基づいたアプリケーションに取り組んでいます。

APIの一部のパスは制限されています。ユーザーがセッションを持っていない場合、返される応答ステータスは401です。クライアント側では、ユーザーをログインページにリダイレクトするために401 httpステータスがインターセプトされます。

ユーザーが認証されると、サーバー側でセッションを作成します

httpRequest.getSession(true);
 Set-Cookie:JSESSIONID = XXXXXXXXXXXXXXXXXXXXX; Domain = localhost; Path =/api /; HttpOnly 

問題は、Cookieがクライアント側に置かれないことです。 localhostドメインのCookieを検査すると空になります。そのため、次のリクエストではヘッダーにこのCookieがなく、クライアント側はAPIの制限されたパスにアクセスできませんでした。

クライアントとサーバーは同じドメインにありますが、同じパスと同じポート番号を持っていません:

クライアント:http://localhost:8000/app/index.html

サーバー:http://localhost:8080/api/restricted/

追加情報:CORSは両側で有効になっています:

「Access-Control-Allow-Methods」、「GET、POST、OPTIONS」
「Access-Control-Allow-Origin」、「*」
 "Access-Control-Allow-Credentials"、本当

Set-cookieを作成するためのアイデアは適切に機能しますか?それはAngularJS関連の問題ですか?

67

AngularJSの問題 が見つかりました。

"Access-Control-Allow-Credentials" : trueがクライアント側で設定されていないようです。命令$httpProvider.defaults.withCredentials = trueは無視されました。

$ resource呼び出しを、configパラメーターで{withCredentials:true}を使用した単純な$ http呼び出しに置き換えます。

21

私はあなたと非常によく似た問題を解決することができました。私のプレイ!バックエンドは、Angularでキャッチしたりブラウザで保存したりできないセッションCookieを設定しようとしました。

実際には、このソリューションにはこれが少し含まれていました。

特定のドメインをAccess-Control-Allow-Originに追加し、ワイルドカードを削除することによってのみ解決できる最初の問題を解決したと仮定すると、次の手順は次のとおりです。

  1. Set-CookieヘッダーからHTTPのみを削除する必要があります。そうしないと、angularコードによって「生成された」Cookieを受信できなくなります。
    この設定はFirefoxでは既に動作しますが、Chromeでは動作しません

  2. Chromeでも機能させるには、以下を行う必要があります。

    a)WSが「ホスト」されているドメインを使用して、Cookieでlocalhostから別のドメインを送信します。 .domain.comの代わりにws.domain.comのようなワイルドカードを使用することもできます

    b)その後、Cookieで指定したドメインを呼び出す必要があります。そうしないと、ChromeはCookieを保存しません

    [オプション] /apiを優先して/パスを削除します


そして、これはトリックのはずです。
いくつかの助けをしたい

17
domokun

クライアント側の投稿リクエストで、次を追加してください。

Jquery ajaxリクエストの場合:

$.ajax({
  url: "http://yoururlgoeshere",
  type: "post",
  data: "somedata",
  xhrFields: {
    withCredentials: true
  }
});

Angularの$ httpサービスで:

$http.post("http://yoururlgoeshere", "somedata", {
  withCredentials: true
});
13
Teliov

HttpOnly を追加すると、ブラウザはプラグインとJavaScriptにCookieを認識させません。これは、より安全なブラウジングの最近の規則です。 J_SESSIONIDに使用する必要がありますが、ここには使用しないでください。

7
Joop Eggen

サーバー側とクライアント側の両方で作業する必要があります。

クライアント

次のいずれかの方法で、$http config withCredentialstrueに設定します。

  1. リクエストごと

    var config = {withCredentials: true};
    $http.post(url, config);
    
  2. すべてのリクエスト

    angular.module("your_module_name").config(['$httpProvider',
      function($httpProvider) {
        $httpProvider.interceptors.Push(['$q',
          function($q) {
            return {
              request: function(config) {
                config.withCredentials = true;
                return config;
              }
            };
          }
        ]);
      }
    ]);
    

サーバー

応答ヘッダーAccess-Control-Allow-Credentialstrueに設定します。

7
Edmond Chui

このような問題を解決しました。

私はこれをやっていて、働いていません...:

  $cookies.put('JSESSIONID', response.data);

クッキーはブラウザに保存されますが、新しいリクエストを送信したとき、すべてのクッキーは私のものを除いて送信されました。 (私のCookieはJSESSIONIDです)

chromeインスペクターを見て、これを見つけました: My session are the JsessionID

問題ISこれは正しいパスではありません!!!

それから私はこれを試し、私のクッキーが送信されました。わーい! :

$cookies.put('JSESSIONID', response.data, {'path':'/'});

これがあなたの場合であるかどうかはわかりませんが、これは私のために働いた。

よろしく!