Cookieを使用したFetch API


198

新しいFetch APIを試していますが、Cookieに問題があります。具体的には、ログインが成功した後、将来のリクエストにCookieヘッダーが含まれますが、Fetchはそのヘッダーを無視しているようで、Fetchで行われたすべてのリクエストは不正です。

Fetchがまだ準備ができていないためか、FetchがCookieで機能しないためですか?

私はアプリをWebpackでビルドします。同じ問題のないReact NativeでもFetchを使用しています。

回答:


279

FetchはデフォルトでCookieを使用しません。Cookieを有効にするには、次のようにします。

fetch(url, {
  credentials: "same-origin"
}).then(...).catch(...);

55
same-originは機能しなくなりました
。include

7
@jpic: 'include'はクロスオリジンリクエストでのみ機能し、同一オリジンリクエストでは機能しません。公式ドキュメント:github.com/github/fetch#sending-cookies
HoldOffHunger

フェッチ付きのjsで読み取り可能な場合にhttponly Cookieを使用する理由は何ですか?
Martin Bajcar、

4
私は信じているsame-origin(これはないより多くのヘッダが(クッキーなど)を尊重されますが、あなたのコードは、応答へのアクセスが制限されてしまうことを意味し、まだ仕事を)。
Coderer 2017

2
@JohnBalvinAriasThx 後で理解したように、cookieをhttponlyにすると、それはで読み取ることはできませんがdocument.cookie、ajaxまたはフェッチ要求で引き続き使用できます。
Martin Bajcar、

183

@Khanetorの回答に加えて、クロスオリジンリクエストで作業している人のために: credentials: 'include'

JSONフェッチリクエストのサンプル:

fetch(url, {
  method: 'GET',
  credentials: 'include'
})
  .then((response) => response.json())
  .then((json) => {
    console.log('Gotcha');
  }).catch((err) => {
    console.log(err);
});

https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials


9
どのようにクッキーを設定しますか?
pomo

2
Cookieはサーバー側から設定されます。私の場合、httponly cookieを使用していました。
Khanetor

3
@Khanetorは、javascriptによってdocument.cookieを使用してCookieを設定し、リクエストを送信できますか?
ospider 2017年

@ospiderヘッダーで送信できます。
10101010

2
@ospiderに値を設定するだけdocument.cookieで、リクエストに含めることができることがわかりました。
skwidbreth

35

解決しました。2つだけf。残忍な日々

私にとっての秘密は以下の通りでした:

  1. POST / api / authを呼び出し、Cookieが正常に受信されたことを確認しました。

  2. 次に、GET / api / users /を呼び出してcredentials: 'include'401 unauthを取得しました。リクエストでCookieが送信されなかったためです。

キーはcredentials: 'include'最初の/api/auth呼び出しにも設定することです。


1
私はまさにあなたの問題を抱えています。セッションCookieは、GETデータ要求で送信されることはありません。そう401。私はAxiosとFetchを試しました。同じ結果。2つの可能性:ログインPOSTは受信したCookieを保存しないか、次のGETデータは保存したCookieを送信
Rhubarb65

@ Rhubarb65、これを獲得するにはcredentials: 'include'、最初に指定する必要がありますPOST /api/auth
user1671599

はい、ありましたが、それで十分です。私は開発サーバープロキシ(クライアントHTTP)を使用しています
Rhubarb65

はい、資格はありましたが十分ではありませんでした。CORSを回避するためにdevserverプロキシを使用していました:(クライアントhttp)-プロキシ-(サーバーhttps)。安全なCookieにはhttpsが必要なため、これはサーバーからのセッションID Cookieがブラウザーで設定されなかったことを意味すると思います。そこで、devserverプロキシにhttps:trueフラグを追加し、それを修正しました
Rhubarb65

1
よく乾杯。あなたの答えはそれが私にブルートフォースの1日しかかからないことを意味しました :)
マイケル

15

2019年にこれを読んでいる場合credentials: "same-origin"は、デフォルト値です。

fetch(url).then

ただし、すべての人が十分に更新されたブラウザを使用しているわけではないことに注意してください。私自身のバージョンのFirefox(60.x、Debian Stretchの最新バージョン)ではデフォルトで設定されていないため、この質問に出くわしました。
philh

2

.net webapi2ユーザーのためにここで正しい答えを追加するだけです。

corsクライアントサイトが別のアドレスから提供されているために使用している場合は、サーバー側の構成webapiにも含める必要がありSupportsCredentials=trueます。

        // Access-Control-Allow-Origin
        // https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
        var cors = new EnableCorsAttribute(Settings.CORSSites,"*", "*");
        cors.SupportsCredentials = true;
        config.EnableCors(cors);

0

これは私にとってはうまくいきます:

import Cookies from 'universal-cookie';
const cookies = new Cookies();

function headers(set_cookie=false) {
  let headers = {
    'Accept':       'application/json',
    'Content-Type': 'application/json',
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
};
if (set_cookie) {
    headers['Authorization'] = "Bearer " + cookies.get('remember_user_token');
}
return headers;
}

次に、呼び出しを作成します。

export function fetchTests(user_id) {
  return function (dispatch) {
   let data = {
    method:      'POST',
    credentials: 'same-origin',
    mode:        'same-origin',
    body:        JSON.stringify({
                     user_id: user_id
                }),
    headers:     headers(true)
   };
   return fetch('/api/v1/tests/listing/', data)
      .then(response => response.json())
      .then(json => dispatch(receiveTests(json)));
    };
  }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.