如何检测服务器端是否禁用Cookie


91

如何在服务器(服务器端)上检测浏览器中的cookie是否已禁用?可能吗?

详细说明:我正在服务器上处理HTTP请求。我想通过Set-Cookie标题设置一个cookie 。那时我需要知道是由客户端浏览器设置cookie还是我对设置cookie的请求将被忽略。


哪里?在浏览器(客户端)中?还是在服务器上?(哪个服务器)
Assaf Lavie,

7
检测在服务器端代码中启用/禁用的cookie,是的。
阿萨夫·拉维(

您的意思是使用动态语言而不是Javascript,因此Cookie始终会添加到客户端浏览器中,因此...没有服务器!
balexandre

Answers:


58

发送包含cookie的重定向响应;处理Cookie的(特殊)重定向URL测试时-如果存在,则重定向到正常处理,否则重定向到错误状态。

请注意,这只能告诉您浏览器允许设置cookie,但不能设置多长时间。我的FF允许我将所有cookie强制为“会话”模式,除非将站点专门添加到例外列表中-FF关闭时,无论服务器指定的到期时间如何,此类cookie都将被丢弃。这是我始终运行FF的模式。


14
除了stackoverflow?
2009年

9
除了许多站点,其中一个确实是SO。
劳伦斯·多尔

43

您可以使用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的情况下才有效!


23
问题是关于如何在服务器端检测cookie。您的代码在客户端运行。
亚当

2
服务器端-但是他没有指定他使用的服务器语言!但是窍门是一样的...写一个cookie,看看它是否在那里...如果存在,则启用cookie,否则...禁用;)
balexandre 2010年

14
他在服务器上使用哪种语言都没有关系。可以根据HTTP请求/响应来回答此问题。
马丁

7
该Javascript代码必须在浏览器中运行,以检测浏览器是否启用了Cookie。它不能在服务器端运行。
洛恩侯爵,

4
@Adam-尽管OP询问服务器端,但是如果您试图通知用户该站点要求启用cookie才能使其正常工作,则可以通过客户端cookie测试来实现(假设启用了JavaScript)。
克里斯(Chris

18

我认为没有直接的检查方法。最好的方法是在cookie中存储一个值,然后尝试读取它们并决定是否启用cookie。


16

检查cookie支持的一种常用方法是通过重定向。

最好仅在用户尝试执行启动会话的操作(例如登录或向购物车中添加某些操作)时执行此操作。否则,根据您的处理方式,您可能会阻止不支持Cookie的用户(或机器人)访问您的整个网站。

首先,服务器会正​​常检查登录数据-如果登录数据有误,则用户会正常接收该反馈。如果正确,则服务器将立即以Cookie响应并重定向到旨在检查该Cookie的页面-该页面可能只是相同的URL,但在查询字符串中添加了一些标志。如果第二页没有收到Cookie,则用户会收到一条消息,指出由于无法在其浏览器上禁用Cookie而无法登录。

如果您已经按照登录表单的重定向后获取模式进行操作,则此设置和对cookie的检查不会添加任何其他请求-可以在现有重定向期间设置cookie,并由加载的目标进行检查重定向后。

现在,为什么我只在用户启动的操作之后(而不是在每次页面加载时)进行cookie测试。我已经看到网站在每个页面上都执行cookie测试,但没有意识到这将对搜索引擎尝试爬网该网站产生影响。也就是说,如果用户启用了cookie,则测试cookie将被设置一次,因此他们只需要在他们请求的第一页上进行重定向,从此以后就不会再进行重定向。但是,对于任何不返回Cookie的浏览器或其他用户代理(例如搜索引擎),每个页面都可能导致重定向。

检查cookie支持的另一种方法是使用Javascript-这样,就不必进行重定向-您可以编写一个cookie并几乎立即将其读回以查看它是否已存储然后被检索。缺点是它在客户端的脚本中运行-即,如果您仍然希望有关是否支持cookie的消息返回到服务器,则仍然必须进行组织-例如使用Ajax调用。

对于我自己的应用程序,我通过在用户登录前在登录屏幕上设置一个包含随机令牌的cookie并在用户提交登录名时检查该令牌的方式来对“登录CSRF”攻击(CSRF攻击的一种)进行某种保护细节。进一步了解Google的Login CSRF。这样做的副作用是,他们登录后,就可以检查Cookie的存在-无需额外的重定向。


5

通常,您可能只需要在用户对网站执行某些操作(例如,提交登录表单,向购物车中添加商品等)之后检查cookie支持。

目前,对我而言,检查Cookie支持与CSRF(跨站请求伪造)预防紧密结合。

您可能应该去其他地方阅读有关CSRF的更多信息,但其背后的想法是其他网站可能会欺骗或您的用户向自己的网站提交隐藏的选择形式。解决方法是在查看者看到表单时设置cookie,并将匹配标记设置为隐藏表单元素,然后在处理表单时,检查cookie和隐藏表单元素是否均已设置并且彼此匹配。如果是尝试CSRF攻击,则该站点将无法提供隐藏字段来匹配用户的cookie,因为在相同来源的策略下,用户的cookie对他们而言是不可读的。

如果提交的表单没有cookie,但确实包含有效的令牌,则您可以由此得出结论:用户已禁用cookie,并抛出一条消息,指示用户应启用cookie并重试。当然,另一种可能性是用户是CSRF尝试攻击的受害者。因此,当cookie不匹配时阻止用户也会产生防止该攻击的副作用。


4

我一直用这个:

navigator.cookieEnabled

根据w3schools的说法,“所有主要浏览器均支持cookieEnabled属性。”

但是,当我使用表单时,这对我有用,我可以在其中指示浏览器发送其他信息。


向我+1。否决票有什么理由?这似乎是一种在JavaScript中检测Cookie阻止的合理方法(对我而言,该方法在Chrome和IE中均适用)。
米兰·加迪安

6
我认为投票否定是因为该问题专门询问了如何从服务器端检测支持。这是在客户端上测试支持的最佳方法。
TJ VanToll 2012年

3
W3Schools显然不是 HTML / Javascript / CSS / etc 的可靠来源。信息。
BryanH 2013年

5
这仅测试浏览器是否支持。它不会测试是否已启用。几乎每个浏览器都支持它,因此这似乎毫无价值。抱歉。
StuckOnSimpleThings

3

尝试将某些东西存储到cookie中,然后再读取它。如果您没有得到期望的结果,则可能禁用了cookie。


许多网站都这样做。无法(在服务器上)确定是否在第一个请求上启用了cookie ,但是您可以实施一个简短的重定向步骤来确定它。
2009年

2

检查此代码,它将为您提供帮助。

<?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());

1

cookie是否被“启用”的问题太布尔。我的浏览器(Opera)具有每个站点的Cookie设置。此外,该设置不是“是/否”。实际上,最有用的形式是“仅会话”,忽略服务器的到期日期。如果您在设置后直接对其进行测试,它将在那里。明天不会。

另外,由于这是您可以更改的设置,因此即使测试是否保留cookie也只会在测试时告诉您有关该设置的信息。我可能已经决定手动接受一个cookie。如果我一直被垃圾邮件发送,我可以(有时会)关闭该站点的cookie。


3
很好,但是我只需要知道我的Set-Cookie标头是否会导致来自同一客户端的下一个请求将附带该cookie。对于我来说,它是永久性的还是仅会话性的对我来说并不重要。
亚历山大·亚诺维兹

1

如果只想检查是否启用了会话cookie(在会话的整个生命周期中都存在的cookie),请将您的会话模式在web.config文件中设置为AutoDetect,则Asp.Net框架会将cookie写入客户端浏览器称为AspxAutoDetectCookieSupport。然后,您可以在Request.Cookies集合中查找此cookie,以检查是否在客户端上启用了会话cookie。

例如,在您的web.config文件集中:

<sessionState cookieless="AutoDetect" />

然后使用以下命令检查是否在客户端上启用了cookie:

if (Request.Cookies["AspxAutoDetectCookieSupport"] != null)  { ... }

边注:默认情况下,此选项设置为UseDeviceProfile,只要客户端支持,即使禁用了cookie,它也会尝试将cookie写入客户端。我觉得这是默认选项有点奇怪,因为它似乎毫无意义-会话将无法在客户端浏览器中将Cookie设置为UseDeviceProfile的情况下禁用Cookie,并且如果您为不支持Cookie的客户端支持无Cookie模式,那么为什么不使用AutoDetect并为禁用了它们的客户端支持无cookie模式...


1
假设ASP.NET最初的问题是技术中立性
David Moorhouse

1

我在上面使用“ 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>

1

NodeJS-服务器端 -Cookie检查重定向中间件-Express会话/ 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()
}

0

cookieEnabled属性返回一个布尔值,该值指定是否在浏览器中启用cookie

<script>
if (navigator.cookieEnabled) {
    // Cookies are enabled
}
else {
    // Cookies are disabled
}
</script>

OP想知道如何在服务器端检测它。
ZiggyTheHamster,2016年

显然,您必须以适合您的应用程序的方式将该信息返回到服务器。应该清楚的是,如果不与浏览器进行交互就无法确定浏览器是否启用了cookie。
史蒂夫,

-1

使用navigator.CookieEnabled启用cookie(它将返回true或false)和Html标签noscript。顺便说一下,navigator.cookieEnabled是javascript,因此请勿以HTML格式输入


1
问题是关于服务器端检查,而不是客户端。
Evan M

-1
<?php   session_start();
if(SID!=null){
  echo "Please enable cookie";
}
?>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.