在 302 重定向期间发回 cookie 是否有任何问题?例如,如果我创建一个返回 url cookie 并在同一个响应中重定向用户,那么任何(现代)浏览器都会忽略 cookie 吗?
8 回答
根据这篇博文:http ://blog.dubbelboer.com/2012/11/25/302-cookie.html所有主流浏览器,IE(6、7、8、9、10)、FF(17)、Safari (6.0.2)、Opera (12.11) 在 Windows 和 Mac 上,在重定向上设置 cookie。对于 301 和 302 重定向都是如此。
正如@Benni 指出的那样:
https://www.chromium.org/administrators/policy-list-3/cookie-legacy-samesite-policies
cookie 的 SameSite 属性指定 cookie 是否应限制为第一方或同一站点上下文。允许 SameSite 的多个值:
- 带有的 cookie
"SameSite=Strict"
只会随同站点请求一起发送。- cookie
"SameSite=Lax"
将随同站点请求或使用“安全”HTTP 方法的跨站点顶级导航一起发送。- cookie
"SameSite=None"
将随同站点和跨站点请求一起发送。
一条通知(以挽救开发人员的生命):
当 cookie 的域为localhost时,IE 和 Edge 在重定向响应中忽略 Set-Cookie 。
解决方案:
使用127.0.0.1而不是localhost。
大多数浏览器都接受 302 重定向的 cookie。我很确定这一点,但我做了一点搜索。并非所有现代浏览器。 Silverlight 客户端 HTTP 堆栈上现已删除/死/ microsoft connect Q/A 的Internet 存档链接忽略 302 重定向响应(2010)上的 Set-Cookie
我想我们现在有一个 IE6 的替代品,它是 Windows Mobile 浏览器......
这是针对此问题的 Chromium 错误(状态为 302 的 HTTP 响应忽略了 Set-cookie)。
我刚刚在 Firefox 和 Safari 上都遇到了这个问题,但不是 Chrome。根据我的测试,这仅在重定向期间域更改时发生。这在 OAuth2 流程中很典型:
- OAuth2 id 提供者(GitHub、Twitter、Google)将浏览器重定向回您的应用
- 您应用的回调 URL 验证授权并设置登录 cookie,然后再次重定向到目标 URL
- 您的目标 URL 加载时未设置任何 cookie。
由于我还没有弄清楚的原因,请求 2 中的一些 cookie 被忽略,而另一些则没有。但是,如果请求 2 返回带有Refresh
标头的 HTTP 200(“元刷新”重定向),则请求 3 正确设置了 cookie。
这是一种非常不受欢迎的方法,但如果您真的不想依赖 30x set-cookie 浏览器行为,您可以meta http-equiv="refresh"
在设置 cookie 时使用 HTML“重定向”。例如,在 PHP 中:
<?php
...
setcookie("cookie", "value", ...);
url="page.php";
?>
<html>
<head><meta http-equiv="refresh" content=1;url="<?=$url?>"></head>
<body><a href="<?=$url?>">Continue...</a></body>
</html>
服务器将使用 200 而不是正确的 300x 重定向发送 Set-Cookie,因此浏览器将存储 cookie,然后执行“重定向”。<a>
如果浏览器不执行元刷新,该链接是一个后备。
在 .Net 上使用 OpenIdConnect / IdentityServer 时遇到此问题,其中一个单独的 API(不同的主机名)处理身份验证并重定向回主站点。
首先(对于本地主机上的开发),您需要将CookieSecure
选项设置为SameAsRequest
或Never
处理http://localhost/
不安全。请参阅Michael Freidgeim的回答。
其次,您需要将CookieSameSite
属性设置为Lax
,否则 cookie 根本不会被保存。Strict
在这里不起作用!
就我而言,我设置了 CookieOptions.Secure =true,但在http://localhost上对其进行了测试,并且浏览器根据设置隐藏了 cookie。
为避免此类问题,您可以设置 cookie Secure 选项以匹配协议 Request.IsHttps,例如
new CookieOptions()
{
Path = "/",
HttpOnly = true,
Secure = Request.IsHttps,
Expires = expires
}