使用 Cookie 获取 API

问题描述 投票:0回答:11

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

是因为 Fetch 还没有准备好,还是 Fetch 不能与 Cookie 配合使用?

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

cookies fetch-api
11个回答
390
投票

Fetch默认不使用cookie。要启用 cookie,请执行此操作

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

314
投票

除了@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


124
投票

刚刚解决了。就两个f。暴力的日子

对我来说,秘诀如下:

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

  2. 然后使用

    credentials: 'include'
    调用 GET /api/users/ 并得到 401 unauth,因为没有随请求发送 cookie。

关键是为第一个

credentials: 'include'
呼叫设置
/api/auth


35
投票

如果您在 2019 年阅读本文,则

credentials: "same-origin"
是默认值。

fetch(url).then

23
投票

以编程方式覆盖浏览器端的

Cookie
标头不起作用

fetch
文档中,提到了 注意某些名称是被禁止的。。而
Cookie
恰好是禁止的标头名称之一,无法以编程方式修改。以下面的代码为例:

  • https://httpbin.org/页面的Chrome DevTools控制台中执行,
    Cookie: 'xxx=yyy'
    将被忽略,如果有的话,浏览器将始终将
    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

有关详细信息,请参阅禁止的标头名称


4
投票

只是为

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

2
投票

这对我有用:

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

2
投票

如果修复凭据后仍然无法正常工作。

我也正在使用:

  credentials: "same-origin"

它曾经可以工作,然后突然不再工作了,经过深入研究,我意识到我已将网站网址更改为

http://192.168.1.100
以在局域网中测试它,这就是用于发送请求的网址,即使我在
http://localhost:3000

所以总而言之,请确保页面的域与获取网址的域匹配。


1
投票

我的问题是我的 cookie 设置在特定的 URL 路径上(例如,

/auth
),但我
fetch
到了不同的路径。我需要将 cookie 的
path
设置为
/


0
投票

如果

fetch
没有发送凭据,即使该请求并非旨在进行跨源调用,这可能是因为由于请求源和源之间的协议差异,该请求被作为跨源处理。响应的位置。

我观察到我的服务器正在返回带有

Location
URL 的
http
标头,而连接是通过
https
建立的。因此,浏览器将请求视为跨域并应用跨域规则。值得注意的是,Firefox(版本 114.0.2)和 Safari(版本 16.1)在这种情况下没有显示任何警告,但 Chrome(版本 114.0.5735.198)显示了
(blocked:mixed-content)
错误,这有助于识别问题。

如果有人感兴趣,在这种特殊情况下,SSL 终止是在反向代理中执行的,但是由于配置错误,

gunicorn
服务器无法正确处理它,特别是与
secure-scheme-headers
forwarded_allow_ips
设置相关。在服务器端解决这些设置后,
fetch
开始在所有浏览器中正常工作。


0
投票

我浪费了三个小时寻找解决方案,所以我决定分享我的发现。

login(email: string, password: string): Promise<User | null> {

  return fetch('http://localhost:8080/api/login', {
    method: 'POST',
    credentials: 'include',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      email: email,
      password: password,
    }),
  })
      .then(response => {
        this.handleError(response);
        return response.ok ? response.json() : null;
      })
}
  1. “credentials: 'include'” 参数必须在接收到
    Set-Cookies
    header 的请求中设置,而不仅仅是我们期望携带 cookie 的后续请求;
  2. 最重要的是,服务器返回的
    Access-Control-Allow-Headers
    必须列出客户端可以发送的所有可能的标头。与您的预期相反,通配符星号值不起作用。如果客户端发送至少一个未知标头,它也会破坏 cors。
© www.soinside.com 2019 - 2024. All rights reserved.