我正在使用api平台构建一个api,并使用react构建前端(使用apiplatform的react模板)。我配置了身份验证,并使用包含jwt的httponly cookie返回客户端。但是当我的前台提出请求时,它不会发送此Cookie ...而且我绝对不知道为什么,我认为它是由浏览器自动完成的,直到它在同一域中。
以下是我的客户端的网络历史记录示例:
我的应用程序在https:// localhost:3000 /
上运行您认为这些要求有什么问题吗?还是有人知道它可能来自什么? 我的应用和api使用https并具有有效的证书...
如果您需要任何其他信息,请随时提问,并谢谢大家!!!
答案 0 :(得分:1)
Cookie会忽略端口,但跨源策略不会。
您使用两个URL(http:// localhost:8443和http:// localhost:3000)。因此,由于端口不同,您的应用正在制作cross origin request。
xhr需要将其 withCredentials 属性设置为 true ,以便发送带有跨域请求的Cookie。 提取要求将其凭据参数设置为 include 。
在服务器端,将 Access-Control-Allow-Credentials 设置为 true 。
还要注意,您的Cookie是 samesite = strict 。在生产中,如果您为应用程序和api使用两个域,则永远不会发送该域。
真正的问题是,为什么使用cookie而不是 Authorization 标头?
答案 1 :(得分:0)
好吧,我不知道...当我尝试解决自己的问题时,我什么都没找到。 我之所以使用Cookie httponly是因为:
非常感谢您对rugolinifr的回答!
答案 2 :(得分:0)
好的,最后还是有问题...我的浏览器没有发送cookie ...
我的身份验证请求返回承载cookie(有效,已通过邮递员测试)
我丢失了一些东西,但我找不到... 我已经设置了凭据,Access-Control-Allow-Credentials,samesite对于将其发送到任何地方都是“无”。还有其他事情要做吗?还是我在做一件愚蠢的小事,这是错的?
答案 3 :(得分:0)
我无法在评论中回答,因为有代码... 因此,它是由api平台(https://api-platform.com/docs/admin/)的react admin库管理的,但是我的配置是这样的:
const fetchHeaders = {
credentials: 'include',
};
const fetchHydra = (url, options = {}) =>
baseFetchHydra(url, {
...options,
headers: new Headers(fetchHeaders),
});
const apiDocumentationParser = (entrypoint) =>
parseHydraDocumentation(entrypoint, { headers: new Headers(fetchHeaders) }).then(
({ api }) => ({ api }),
(result) => {
...
},
);
const dataProvider = baseHydraDataProvider(entrypoint, fetchHydra, apiDocumentationParser, true);
因此,所有对数据的获取,发布等请求均基于此会议
但是我的第一个身份验证请求是这样完成的:
login: ({ username, password }) => {
const request = new Request(`${entrypoint}/authentication_token`, {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
return fetch(request).then((response) => {
if (response.status < 200 || response.status >= 300) {
localStorage.removeItem('isAuthenticated');
throw new Error(response.statusText);
}
localStorage.setItem('isAuthenticated', 'true');
});
},
答案 4 :(得分:0)
好的,我找到了解决方案: 向身份验证请求添加凭据,如果未添加标头,则浏览器将不会存储cookie。 第二点:
const fetchHydra = (url, options = {}) =>
baseFetchHydra(url, {
...options,
credentials: 'include',
});
credentials: 'include'
不在标题选项中...不错!