web-dev-qa-db-ja.com

Angularjs $ httpは、応答の「Set-Cookie」を理解していないようです

NodejsエクスプレスREST api認証用のPassportモジュールを使用しています。ログインメソッド(GET)はヘッダーにcookieを返します。Chrome正常に動作し、Cookieがブラウザに設定されます。

しかし、Angularjsから$ httpを介して呼び出した場合、Cookieは設定されません。

Set-Cookie:connect.sid=s%3Ad7cZf3DSnz-IbLA_eNjQr-YR.R%2FytSJyd9cEhX%2BTBkmAQ6WFcEHAuPJjdXk3oq3YyFfI; Path=/; HttpOnly

上記を見るとわかるように、Set-Cookieはhttpサービス応答のヘッダーにあります。

おそらくHttpOnlyがこの問題の原因かもしれませんか?はいの場合、どのように変更できますか?これが私のエクスプレス構成です:

app.configure(function () {
    app.use(allowCrossDomain);
    app.use(express.bodyParser());
    app.use(express.cookieParser())
    app.use(express.session({ secret: 'this is a secret' }));
    app.use(flash());
    //passport init
    app.use(passport.initialize());
    app.use(passport.session());
    app.set('port', process.env.PORT || 8080);
});

ご協力ありがとうございました

25
Fred Mériot

資格情報を使用するように$ httpリクエストを構成してください。 XHRドキュメントから:

https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

XMLHttpRequestとAccess Controlの両方で公開される最も興味深い機能は、HTTP CookieとHTTP認証情報を認識する「資格のある」要求を作成する機能です。デフォルトでは、クロスサイトXMLHttpRequest呼び出しで、ブラウザーは資格情報を送信しません。 XMLHttpRequestオブジェクトが呼び出されたときに、特定のフラグを設定する必要があります。

オプションオブジェクトを使用して、資格情報の使用を設定できます。

http://docs.angularjs.org/api/ng.$http

例:

$http({withCredentials: true, ...}).get(...)
19
Thomas

Cookieの存在をどのように確認していますか?

$httpは、jQueryの$.ajaxや友人と同じように、ブラウザーのXHRの単なるラッパーです。つまり、ブラウザは通常どおりにCookieを処理します。

私の推測では、Cookieは設定されているが、document.cookieを介してそれを読み取ろうとしている。 HttpOnlyは、スクリプトがCookieにアクセスできないようにします。 これは良いことです。

HttpOnlyは、XSS攻撃の緩和に役立ちます。悪意のあるスクリプトがユーザーのセッショントークン(およびログイン)を盗むことを不可能にします。 HttpOnlyをオフにしないでください

とにかくクッキーは必要ないはずです。 $httpはXHRの単なるラッパーであるため、ブラウザは次回リクエストを行うときに自動的にCookieを送信します。これを確認するには、Developer Toolsの[ネットワーク]パネルでリクエストを確認します。

5
josh3736

angular {withCredential : true}リクエストで$httpを設定し、次を設定することで問題を解決しました。

res.header("Access-Control-Allow-Credentials", true);

私のエクスプレスサーバー構成で。これを行うことにより、私のCookieはブラウザーのCookieリストに正しく表示されます。

5
Fred Mériot

以下のソリューションが私のために働いた

Angularでは、リクエストにwithCredentials: trueを使用して次のコードスニペットを使用しました。

this._http.post(this._apiUrl + 'api/' + url, data, { withCredentials: true })
            .subscribe(data => { resolve(data) }, error => { this.showServerError(error)})

Nodeでは、ソリューションを取得する前に、[〜#〜] cors [〜#〜]を初期化するだけでした。

app.use(cors());

しかし、今、私は次のコードスニペットを実装しました

app.use(cors({Origin: [
   "http://localhost:5000"
 ], credentials: true}))

http:// localhost:50 is my Angularアプリケーションエンドポイント。このURLは、configまたは.envファイルから動的に設定できます。

上記の解決策が問題に役立つことを願っています。

2
Vatsal Shah

express.sessionを構成することで変更できます:

app.use(express.session({
  secret : 'this is a secret',
  cookie : {
    httpOnly : false,
    maxAge   : XXX // see text
  }
});

しかし、私はAngularがCookieを大事にしているので、それらはブラウザによって処理されます(そして、httpOnlytrueに保つ必要があるという@ josh3736に同意します)。

それはあなたのクッキーが(ブラウザ)セッションクッキーであることと関係があるかもしれません。 Cookieに対してmaxAgeを明示的に設定することで(ミリ秒単位で)うまく機能するかどうかを確認できます。

0
robertklep