使用Cookie获取API

我正在尝试新的Fetch API,但cookie有问题。具体来说,在成功登录后,在未来的请求中有一个Cookie报头,但Fetch似乎忽略了这个报头,并且我所有的请求都是未经授权的。

是因为Fetch还没有准备好,还是Fetch不能与cookie一起工作?

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

347182 次浏览

默认情况下,Fetch不使用cookie。要启用cookie, 这样做:

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

除了@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 < a href = " https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials " > < / >

刚刚解出来。只是两天的蛮力

对我来说,秘诀如下:

  1. 我调用POST /api/auth,看到cookie被成功接收。

  2. 然后用credentials: 'include'调用GET /api/users/,得到401 unauth,因为请求中没有发送cookie。

KEY也是为第一次/api/auth调用设置credentials: 'include'

如果你是在2019年读这篇文章,credentials: "same-origin"是默认值。

fetch(url).then

只是在这里为.net webapi2用户添加正确答案。

如果你正在使用cors,因为你的客户端站点与你的webapi地址不同,那么你还需要在服务器端配置中包含SupportsCredentials=true

        // Access-Control-Allow-Origin
// https://learn.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);

这对我来说很管用:

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)));
};
}

我的问题是我的cookie被设置在一个特定的URL路径上(例如,/auth),但我是fetching到一个不同的路径。我需要将cookie的path设置为/

以编程方式覆盖浏览器端不会起作用中的Cookie报头。

fetch文档中提到了注意,有些名称是禁止的。。而Cookie恰好是禁止的头名称之一,不能通过编程方式修改。以下面的代码为例:

  • 在Chrome DevTools控制台的https://httpbin.org/页中执行,Cookie: 'xxx=yyy'将被忽略,如果有cookie,浏览器将始终将document.cookie的值作为cookie发送。
  • 如果在不同的源上执行,则不会发送cookie。
fetch('https://httpbin.org/cookies', {
headers: {
Cookie: 'xxx=yyy'
}
}).then(response => response.json())
.then(data => console.log(JSON.stringify(data, null, 2)));

附注:你可以通过在chrome浏览器中打开https://httpbin.org/cookies/set/foo/bar来创建一个样例cookie foo=bar

详见禁止使用的头名称

如果它仍然不能为您修复凭证后。

我还用了:

  credentials: "same-origin"

它曾经工作,然后它不再突然,在挖掘了很多之后,我意识到我已经把我的网站url改为http://192.168.1.100来测试它在LAN,这是用来发送请求的url,即使我是在http://localhost:3000上。

总之,要确保页面的域与获取url的域相匹配。