如何检测服务器端cookie是不是被禁用
Posted
技术标签:
【中文标题】如何检测服务器端cookie是不是被禁用【英文标题】:How to detect server-side whether cookies are disabled如何检测服务器端cookie是否被禁用 【发布时间】:2010-10-06 14:15:12 【问题描述】:如何在服务器(服务器端)检测浏览器中的 cookie 是否被禁用?有可能吗?
详解:我正在服务器上处理一个HTTP请求。我想通过Set-Cookie
标头设置一个cookie。那时我需要知道cookie是由客户端浏览器设置还是我设置cookie的请求会被忽略。
【问题讨论】:
在哪里?在浏览器中(客户端)?还是在服务器上? (哪个服务器) 检测在服务器端代码中启用/禁用的 cookie,是的。 你的意思是使用动态语言而不是 javascript,Cookie 总是添加到客户端浏览器,所以...没有服务器! 【参考方案1】:发送带有 cookie 集的重定向响应;在处理 cookie 的(特殊)重定向 URL 测试时 - 如果它在那里重定向到正常处理,否则重定向到错误状态。
请注意,这只能告诉您浏览器允许设置 cookie,但不能告诉您设置多长时间。我的 FF 允许我强制所有 cookie 进入“会话”模式,除非该站点被明确添加到例外列表中 - 当 FF 关闭时,无论服务器指定的到期时间如何,此类 cookie 都将被丢弃。这就是我一直运行 FF 的模式。
【讨论】:
除了一些网站,其中一个确实如此。【参考方案2】:您可以使用 Javascript 来完成此操作
图书馆:
function createCookie(name, value, days)
var expires;
if (days)
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
else expires = "";
document.cookie = name + "=" + value + expires + "; path=/";
function readCookie(name)
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++)
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
return null;
function eraseCookie(name)
createCookie(name, "", -1);
function areCookiesEnabled()
var r = false;
createCookie("testing", "Hello", 1);
if (readCookie("testing") != null)
r = true;
eraseCookie("testing");
return r;
要运行的代码:
alert(areCookiesEnabled());
记住
这只有在启用 Javascript 时才有效!
【讨论】:
问题是关于如何在服务器端检测cookie。您的代码在客户端运行。 服务器端 - 但他没有指定他使用的服务器语言!但诀窍是一样的......写一个cookie,看看它是否在那里......如果是,Cookies Enabled,如果不是...... Disabled ;) 不管他在服务器上使用什么语言。这个问题可以用 HTTP 请求/响应来回答。 该Javascript代码必须在浏览器中运行以检测浏览器是否启用了cookies。它不能在服务器端运行。 @Adam - 虽然 OP 询问了服务器端,但如果您试图通知用户该站点需要启用 cookie 才能完全工作,客户端 cookie 测试可以实现这一点(假设JavaScript 已启用)。【参考方案3】:我认为没有直接的方法可以检查。最好的方法是在 cookie 中存储一个值并尝试读取它们并决定是否启用 cookie。
【讨论】:
【参考方案4】:检查 cookie 支持的常用方法是通过重定向。
最好仅在用户尝试执行某些会启动会话的操作时执行此操作,例如登录或将某些内容添加到他们的购物车。否则,根据您的处理方式,您可能会阻止不支持 Cookie 的用户(或机器人)访问您的整个网站。
首先,服务器正常检查登录数据 - 如果登录数据错误,用户将正常接收反馈。如果正确,则服务器立即响应 cookie 并重定向到旨在检查该 cookie 的页面 - 这可能只是相同的 URL,但在查询字符串中添加了一些标志。如果第二个页面没有收到 cookie,那么用户会收到一条消息,指出他们无法登录,因为 cookie 在他们的浏览器上被禁用。
如果您的登录表单已经遵循 Post-Redirect-Get 模式,那么此 cookie 设置和检查不会添加任何额外的请求 - cookie 可以在现有重定向期间设置,并由重定向后加载的目的地。
现在解释为什么我只在用户发起的操作之后而不是在每次页面加载时进行 cookie 测试。我已经看到网站在每个页面上都实施了 cookie 测试,但没有意识到这会对尝试爬取网站的搜索引擎产生影响。也就是说,如果用户启用了 cookie,则测试 cookie 设置一次,因此他们只需要在他们请求的第一个页面上忍受重定向,从那时起就没有重定向了。但是,对于任何不返回 cookie 的浏览器或其他用户代理(如搜索引擎),每个页面都可能简单地导致重定向。
另一种检查 cookie 支持的方法是使用 Javascript - 这样,不一定需要重定向 - 您可以编写一个 cookie 并立即将其读回以查看它是否已存储然后检索。这样做的缺点是它在 客户端 的脚本中运行 - 即,如果您仍然希望有关是否支持 cookie 的消息返回到服务器,那么您仍然必须组织它 - 例如使用 Ajax 调用。
对于我自己的应用程序,我通过在用户登录之前在登录屏幕上设置一个包含随机令牌的 cookie,并在用户登录时检查该令牌,实现了对“登录 CSRF”攻击(CSRF 攻击的一种变体)的一些保护提交他们的登录详细信息。阅读更多关于谷歌登录 CSRF 的信息。这样做的副作用是,当他们登录时,我可以检查该 cookie 的存在 - 不需要额外的重定向。
【讨论】:
【参考方案5】:通常,您可能只需要在用户在网站上执行某些操作(例如提交登录表单、将商品添加到购物车等)后检查 cookie 支持。
目前对我而言,检查 cookie 支持与防止 CSRF(跨站点请求伪造)密切相关。
您可能应该去其他地方阅读more about CSRF,但其背后的想法是其他网站可能会欺骗或您的用户将他们选择的隐藏表单提交到您自己的网站。解决这个问题的方法是在查看者看到表单时设置一个 cookie,并将匹配的标记设置为隐藏的表单元素,然后在处理表单时,检查 cookie 和隐藏的表单元素是否已设置并相互匹配。如果是 CSRF 攻击尝试,网站将无法提供隐藏字段来匹配用户的 cookie,因为在同源策略下,用户的 cookie 将无法被他们读取。
如果提交的表单没有 cookie,但它确实包含看起来有效的令牌,那么您可以由此得出结论,用户禁用了 cookie,并抛出一条消息,指示用户应该启用 cookie 并重试.当然,另一种可能性是用户是 CSRF 攻击的受害者。因此,当 cookie 不匹配时阻止用户也会产生防止该攻击的副作用。
【讨论】:
【参考方案6】:尝试将某些内容存储到 cookie 中,然后读取它。如果您没有得到您期望的结果,那么 cookie 可能已被禁用。
【讨论】:
很多网站都这样做。 (在服务器上)无法确定 first 请求是否启用了 cookie,但您可以执行一个简短的重定向步骤来确定。【参考方案7】:我一直用这个:
navigator.cookieEnabled
根据w3schools“所有主流浏览器都支持cookieEnabled属性。”。
但是,当我使用表单时,这对我有用,我可以指示浏览器发送附加信息。
【讨论】:
+1 来自我。否决票的任何理由?这似乎是一种在 JavaScript 中检测 cookie 阻塞的合理方法(对我来说适用于 Chrome 和 IE)。 我认为否决票是因为该问题专门询问了如何检测服务器端的支持。这是在客户端测试支持的最佳方式。 W3Schools 显然是not a credible source 用于 html/Javascript/CSS/等。信息。 这仅测试浏览器是否支持它。它不会测试它是否已启用。几乎每个浏览器都支持它,所以这似乎毫无价值。对不起。【参考方案8】:检查此代码,它将对您有所帮助。
<?php
session_start();
function visitor_is_enable_cookie()
$cn = 'cookie_is_enabled';
if (isset($_COOKIE[$cn]))
return true;
elseif (isset($_SESSION[$cn]) && $_SESSION[$cn] === false)
return false;
// saving cookie ... and after it we have to redirect to get this
setcookie($cn, '1');
// redirect to get the cookie
if(!isset($_GET['nocookie']))
header("location: ".$_SERVER['REQUEST_URI'].'?nocookie') ;
// cookie isn't availble
$_SESSION[$cn] = false;
return false;
var_dump(visitor_is_enable_cookie());
【讨论】:
【参考方案9】:NodeJS - 服务器端 - Cookie 检查重定向 中间件 - Express Session/Cookie 解析器
依赖关系
var express = require('express'),
cookieParser = require('cookie-parser'),
expressSession = require('express-session')
中间件
return (req, res, next) =>
if(req.query.cookie && req.cookies.cookies_enabled)
return res.redirect('https://yourdomain.io' + req.path)
if(typeof(req.cookies.cookies_enabled) === 'undefined' && typeof(req.query.cookie) === 'undefined')
return res.cookie('cookies_enabled', true,
path: '/',
domain: '.yourdomain.io',
maxAge: 900000,
httpOnly: true,
secure: process.env.NODE_ENV ? true : false
).redirect(req.url + '?cookie=1')
if(typeof(req.cookies.cookies_enabled) === 'undefined')
var target_page = 'https://yourdomain.io' + (req.url ? req.url : '')
res.send('You must enable cookies to view this site.<br/>Once enabled, click <a href="' + target_page + '">here</a>.')
res.end()
return
next()
【讨论】:
【参考方案10】:cookie 是否“启用”的问题太布尔了。我的浏览器 (Opera) 具有每个站点的 cookie 设置。此外,该设置不是是/否。最有用的形式实际上是“仅会话”,忽略服务器的到期日期。如果设置后直接测试它,它就会在那里。明天就不行了。
此外,由于这是一个您可以更改的设置,因此即使测试 cookie 是否保留也只会告诉您有关设置测试时的信息。我可能已经决定手动接受那个 cookie。如果我不断收到垃圾邮件,我可以(有时会)关闭该网站的 cookie。
【讨论】:
好点,但我只需要知道我的 Set-Cookie 标头是否会导致来自同一客户端的下一个请求将带有该 cookie。对我来说,它是永久的还是只是会话的并不重要。【参考方案11】:如果您只想检查是否启用了会话 cookie(在会话期间存在的 cookie),请在 web.config 文件中将会话模式设置为 AutoDetect,然后将 Asp. Net 框架会向客户端浏览器写入一个名为 AspxAutoDetectCookieSupport 的 cookie。然后,您可以在 Request.Cookies 集合中查找此 cookie,以检查客户端上是否启用了会话 cookie。
例如在您的 web.config 文件集中:
<sessionState cookieless="AutoDetect" />
然后检查客户端是否启用了cookie:
if (Request.Cookies["AspxAutoDetectCookieSupport"] != null) ...
旁注:默认设置为 UseDeviceProfile,只要客户端支持它们,它将尝试将 cookie 写入客户端,即使 cookie 被禁用。我觉得这是默认选项有点奇怪,因为它似乎毫无意义 - 会话将无法在客户端浏览器中禁用 cookie 并将其设置为 UseDeviceProfile,并且如果您支持不支持 cookie 的客户端的无 cookie 模式,那么为什么不使用 AutoDetect 并为禁用它们的客户端支持 cookieless 模式...
【讨论】:
假设 ASP.NET 最初的问题是技术中立的【参考方案12】:我使用的是上面“balexandre”答案的更简化版本。它尝试设置和读取会话 cookie,其唯一目的是确定是否启用了 cookie。是的,这也需要启用 JavaScript。因此,如果您想在其中放置一个标签,则可能需要一个标签。
<script>
// Cookie detection
document.cookie = "testing=cookies_enabled; path=/";
if(document.cookie.indexOf("testing=cookies_enabled") < 0)
// however you want to handle if cookies are disabled
alert("Cookies disabled");
</script>
<noscript>
<!-- However you like handling your no JavaScript message -->
<h1>This site requires JavaScript.</h1>
</noscript>
【讨论】:
【参考方案13】:cookieEnabled
属性返回一个布尔值,指定浏览器中是否启用 cookie
<script>
if (navigator.cookieEnabled)
// Cookies are enabled
else
// Cookies are disabled
</script>
【讨论】:
OP 想知道如何在服务器端检测它。 显然,您必须以适合您的应用程序的方式将该信息返回到服务器。应该清楚的是,如果不与浏览器交互,就无法确定浏览器是否启用了 cookie。【参考方案14】:<?php session_start();
if(SID!=null)
echo "Please enable cookie";
?>
【讨论】:
【参考方案15】:使用 navigator.CookieEnabled 启用 cookie(它将返回 true 或 false)和 Html 标签 noscript。顺便说一下 navigator.cookieEnabled 是 javascript 所以不要把它输入为 HTML
【讨论】:
问题是关于服务器端检查,而不是客户端。以上是关于如何检测服务器端cookie是不是被禁用的主要内容,如果未能解决你的问题,请参考以下文章