使用Cookie提取API


198

我正在尝试新的Fetch API,但Cookie遇到问题。具体来说,成功登录后,以后的请求中会有一个Cookie标头,但是Fetch似乎忽略了这些标头,并且我使用Fetch进行的所有请求都是未经授权的。

是因为Fetch尚未准备就绪还是Fetch无法与Cookie配合使用?

我使用Webpack构建我的应用程序。我还在React Native中使用Fetch,它没有相同的问题。

Answers:


279

提取默认情况下不使用cookie。要启用Cookie,请执行以下操作:

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

54
same-origin不再起作用,包括它(请参阅
@Jerry

7
@jpic:“包含”仅适用于跨源请求,而不适用于相同源请求。官方文档:github.com/github/fetch#sending-cookies
HoldOffHunger

那么,如果在具有fetch的js中可以读取httponly cookie的话,那是什么原因呢?
马丁·巴伊卡尔

4
我相信same-origin(这确实仍然工作)意味着更多的头将得到尊重(饼干等),但你的代码将不得不响应有限。
编码器

2
@JohnBalvinAriasThx。后来我了解到,拥有cookie httponly意味着它无法被读取document.cookie,但仍可用于ajax或提取请求。
马丁·巴伊卡尔

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/zh-CN/docs/Web/API/Request/credentials


9
您如何设置cookie?
pomo

2
cookie是从服务器端设置的。就我而言,我使用的是httponly cookie。
Khanetor

3
@Khanetor是否可以通过javascript使用document.cookie设置cookie,然后发送请求?
ospider

@ospider您可以在标题中发送它。
10101010

2
@ospider我发现仅设置值document.cookie就足以将其包含在请求中。
skwidbreth '18

35

刚刚解决。只有两个f。暴力之日

对我而言,秘密在于:

  1. 我打电话给POST / api / auth,看到成功接收了cookie。

  2. 然后使用来调用GET / api / users / credentials: 'include'并获得401 unauth,因为没有随请求一起发送cookie。

KEY也将设置credentials: 'include'为第一个/api/auth呼叫。


1
我有你的问题。会话cookie永远不会在GET数据请求上发送。所以401。我尝试过Axios和Fetch。同样的结果。2种可能性:登录POST不存储收到的cookie,或者以下GET数据不发送保存的cookie
Rhubarb65 '18

@ Rhubarb65,要赢得这场比赛,您应该credentials: 'include'首先指定POST /api/auth
user1671599 '18

是的,我有,但是它足够了。我使用devserver代理(客户端Http)
Rhubarb65 '18

是的,我有凭据,但这还不够。我正在使用devserver代理来通过CORS :(客户端http)-代理-(服务器https)。我认为这意味着未在浏览器中设置服务器的sessionid cookie,因为安全cookie需要使用https。因此,我在devserver代理中添加了标志https:true,并对其进行了修复
Rhubarb65 '18

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)));
    };
  }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.