Pim*_*den 35 authentication cookies localhost http-headers cors
如何共享cookie跨源?更具体地说,如何将Set-Cookie标题与标题结合使用Access-Control-Allow-Origin?
这是我的情况的解释:
我正在尝试localhost:4000为托管在其上的Web应用程序中运行的API设置cookie localhost:3000.
我似乎在浏览器中收到了正确的响应标题,但不幸的是它们没有任何效果.这些是响应标头:
HTTP/1.1 200 OK Access-Control-Allow-Origin: http://localhost:3000 Vary: Origin, Accept-Encoding Set-Cookie: token=0d522ba17e130d6d19eb9c25b7ac58387b798639f81ffe75bd449afbc3cc715d6b038e426adeac3316f0511dc7fae3f7; Max-Age=86400; Domain=localhost:4000; Path=/; Expires=Tue, 19 Sep 2017 21:11:36 GMT; HttpOnly Content-Type: application/json; charset=utf-8 Content-Length: 180 ETag: W/"b4-VNrmF4xNeHGeLrGehNZTQNwAaUQ" Date: Mon, 18 Sep 2017 21:11:36 GMT Connection: keep-alive
此外,Response Cookies当我使用Chrome开发者工具的"网络"标签检查流量时,我可以看到cookie .但是,我看不到在"应用程序"选项卡下设置的cookie Storage/Cookies.我没有看到任何CORS错误,所以我假设我错过了其他的东西.
有什么建议?
我正在使用React-Redux应用程序中的请求模块/signin向服务器上的端点发出请求.对于服务器我使用快递.
快递服务器:
res.cookie('token', 'xxx-xxx-xxx', { maxAge: 86400000, httpOnly: true, domain: 'localhost:3000' })
在浏览器中请求:
request.post({ uri: '/signin', json: { userName: 'userOne', password: '123456'}}, (err, response, body) => {
// doing stuff
})
我现在设置请求和响应标头现在像疯了一样,确保它们在请求和响应中都存在.下面是截图.注意头Access-Control-Allow-Credentials,Access-Control-Allow-Headers,Access-Control-Allow-Methods和Access-Control-Allow-Origin.看看我在Axios的github上发现的问题,我的印象是现在已经设置了所有必需的标题.然而,仍然没有运气......
Pim*_*den 64
要允许成功通过CORS请求接收和发送cookie,请执行以下操作.
后端(服务器):
将HTTP标头Access-Control-Allow-Credentials值设置为true.此外,请确保Access-Control-Allow-Origin已设置HTTP标头.
前端(客户端):将*标志设置为XMLHttpRequest.withCredentials,这可以通过不同的方式实现,具体取决于所使用的请求 - 响应库:
jQuery 1.5.1 true
ES6 fetch() xhrFields: {withCredentials: true}
axios:credentials: 'include'
避免将CORS与cookie结合使用.您可以使用代理实现此目的.
如果你出于某种原因不要避免它.解决方案如上.
事实证明,如果域包含端口,Chrome将不会设置cookie.设置它withCredentials: true(没有端口)不是问题.非常感谢Erwin的提示!
Len*_*Lip 29
2020 年发布的 Chrome 浏览器注意事项。
未来版本的 Chrome 将仅在跨站点请求中使用
SameSite=None和设置 cookie 时才传送 cookieSecure。
因此,如果您的后端服务器未设置 SameSite=None,Chrome 将默认使用 SameSite=Lax,并且不会将此 cookie 与 { withCredentials: true } 请求一起使用。
更多信息https://www.chromium.org/updates/same-site。
Firefox 和 Edge 开发人员也希望在未来发布此功能。
规范在这里找到:https : //tools.ietf.org/html/draft-west-cookie-incrementalism-01#page-8
Ste*_*gas 11
为了让客户端能够从跨域请求中读取 cookie,您需要具备:
来自服务器的所有响应都需要在其标头中包含以下内容:
Access-Control-Allow-Credentials: true
客户端需要发送所有带有withCredentials: true选项的请求
在我使用 Angular 7 和 Spring Boot 的实现中,我通过以下方式实现了这一点:
服务器端:
@CrossOrigin(origins = "http://my-cross-origin-url.com", allowCredentials = "true")
@Controller
@RequestMapping(path = "/something")
public class SomethingController {
...
}
Run Code Online (Sandbox Code Playgroud)
该origins = "http://my-cross-origin-url.com"部分将添加Access-Control-Allow-Origin: http://my-cross-origin-url.com到每个服务器的响应头
该allowCredentials = "true"部分将添加Access-Control-Allow-Credentials: true到每个服务器的响应头中,这是我们让客户端读取 cookie 所需要的
客户端:
import { HttpInterceptor, HttpXsrfTokenExtractor, HttpRequest, HttpHandler, HttpEvent } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from 'rxjs';
@Injectable()
export class CustomHttpInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// send request with credential options in order to be able to read cross-origin cookies
req = req.clone({ withCredentials: true });
// return XSRF-TOKEN in each request's header (anti-CSRF security)
const headerName = 'X-XSRF-TOKEN';
let token = this.tokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
}
return next.handle(req);
}
}
Run Code Online (Sandbox Code Playgroud)
通过这个类,您实际上可以为您的所有请求注入额外的内容。
第一部分req = req.clone({ withCredentials: true });,是您发送带有withCredentials: true选项的每个请求所需要的。这实际上意味着将首先发送一个 OPTION 请求,以便您在发送实际的 POST/PUT/DELETE 请求之前获得您的 cookie 和其中的授权令牌,这些请求需要将此令牌附加到它们(在标头中),在命令服务器验证并执行请求。
第二部分是专门处理所有请求的反 CSRF 令牌的部分。在需要时从 cookie 中读取它并将其写入每个请求的标头中。
想要的结果是这样的:
对于 Express,请将 Express 库升级到4.17.1最新的稳定版本。然后;
在 CorsOption 中:设置origin为您的本地主机 url 或前端生产 url
,credentials例如true
const corsOptions = {
origin: config.get("origin"),
credentials: true,
};
Run Code Online (Sandbox Code Playgroud)
我使用config npm module动态设置我的原点。
然后,在 res.cookie 中:
对于 localhost:您根本不需要设置 SameSite 和 secure 选项,您可以根据您的用例httpOnly设置truehttp cookie 以防止 XSS 攻击和其他有用的选项。
对于生产环境,跨域请求需要设置为sameSiteto ,跨域请求需要设置为to 。请记住,仅适用于 Express 最新版本,因为目前最新的 chrome 版本仅设置 cookie ,因此需要安全选项。nonesecuretruesameSitehttps
这是我如何让我的动态变得动态
res
.cookie("access_token", token, {
httpOnly: true,
sameSite: app.get("env") === "development" ? true : "none",
secure: app.get("env") === "development" ? false : true,
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
38834 次 |
| 最近记录: |