为什么会说:‘Cookie被阻止或不受支持’?

时间:2019-03-11 作者:Zeth

many many many many 关于这个问题的页面(我可以继续)。

对于那些刚刚来到这里寻求解决方案的人来说,那就是:

1) 请尝试刷新页面。

2) 试着把这个放进你的wp-config.php

define(\'ADMIN_COOKIE_PATH\', \'/\');
define(\'COOKIE_DOMAIN\', \'\');
define(\'COOKIEPATH\', \'\');
define(\'SITECOOKIEPATH\', \'\'); 
3) 或者试着把这个放进你的wp-config.php

define(\'COOKIE_DOMAIN\', $_SERVER[\'HTTP_HOST\'] );
4) 或者把这个放进你的functions.php:

setcookie(TEST_COOKIE, \'WP Cookie check\', 0, COOKIEPATH, COOKIE_DOMAIN);
if ( SITECOOKIEPATH != COOKIEPATH ) setcookie(TEST_COOKIE, \'WP Cookie check\', 0, SITECOOKIEPATH, COOKIE_DOMAIN);
5) W3缓存缓存的登录页

如果您更改了登录url(如WPS Hide Login), 然后记住添加新URL作为例外。在W3缓存中,它位于:Performance>&燃气轮机;页面缓存(>)&燃气轮机;从不缓存以下页面<这花了我半天的时间才弄明白

但是

我找不到人解释为什么会这样?我在当地的开发环境中体验到了这种情况,但我想确保在我投入生产时不会发生这种情况。

为什么会发生这种错误。。。为什么一个简单的刷新就可以绕过它呢?

3 个回复
最合适的回答,由SO网友:MikeNGarrett 整理而成

When you log in to the admin WordPress sets cookies (in PHP) to keep you logged in while you navigate around your site. If this fails, you get the error message, "Cookies are blocked or not supported by your browser."

This could fail in a couple different ways, but before we dig into those situations, let\'s take a look at the source of these error messages:

wp-login.php v5.1.1

    if ( empty( $_COOKIE[ LOGGED_IN_COOKIE ] ) ) {
        if ( headers_sent() ) {
            $user = new WP_Error(
                \'test_cookie\',
                sprintf(
                    /* translators: 1: Browser cookie documentation URL, 2: Support forums URL */
                    __( \'<strong>ERROR</strong>: Cookies are blocked due to unexpected output. For help, please see <a href="%1$s">this documentation</a> or try the <a href="%2$s">support forums</a>.\' ),
                    __( \'https://codex.wordpress.org/Cookies\' ),
                    __( \'https://wordpress.org/support/\' )
                )
            );
        } elseif ( isset( $_POST[\'testcookie\'] ) && empty( $_COOKIE[ TEST_COOKIE ] ) ) {
            // If cookies are disabled we can\'t log in even with a valid user+pass
            $user = new WP_Error(
                \'test_cookie\',
                sprintf(
                    /* translators: %s: Browser cookie documentation URL */
                    __( \'<strong>ERROR</strong>: Cookies are blocked or not supported by your browser. You must <a href="%s">enable cookies</a> to use WordPress.\' ),
                    __( \'https://codex.wordpress.org/Cookies\' )
                )
            );
        }
    }

Failure Context

1. LOGGED_IN_COOKIE check

If the LOGGED_IN_COOKIE is missing, something has gone wrong and we cannot continue. This is the first indication there\'s a problem. The code then checks for 2 more specific issues to clarify the error message returned.

2. headers_sent check

The first test is for headers_sent which is a core PHP function to determine whether or not your response headers have been put together and sent back to the user making the request. They should not be sent by this point. If they are, you have a problem that needs to be resolved before a user can log in.

This is also the least commonly addressed case for most issues raised here for this question. It also generates a slightly different error message.

Cookies are blocked due to unexpected output.

3. Test Cookie status

In this test, WordPress tried setting a test cookie and that failed. Notice that the check is for both the POST request parameter and missing cookie. The POST parameter comes from a hidden field on the login form: <input type="hidden" name="testcookie" value="1" />. The cookie name default is wordpress_test_cookie, but can be changed via the TEST_COOKIE constant. More on this in a bit.

This is the most common scenario. Something has gone wrong that prevents either the POST parameter from being set or the test cookie from being set.

Let\'s take a look at the scenarios that could cause this to happen.

Common Problems and Solutions

1. Your browser blocks cookies

This is the original intention of these checks. It\'s common for browsers to block "unsafe" cookies or common trackers. It\'s even pretty common for most people to block cookies altogether and only allow certain cookies to be set after they\'re discovered (or not at all). This is why the error message is worded this way.

Solution: enable cookies in your browser.

2. Your site is sending headers prematurely

Somewhere in your code you probably have a call to send headers like this: header(\'Location: https://google.com/\'); (for example). Sending a header this way can kill off the process of building the entire header before sending it as a response. I\'m not going to go into more detail here because you\'d also get a different error message. Read more: Login page error cookies are blocked due to unexpected output.

Solution: check that you\'re not sending headers prematurely.

3. Cookies aren\'t being saved

This is the most common situation developers run into, especially when migrating sites.

setcookie( $name , $value, $expires ); 

Cookies are fairly simple. They typically have a name, value, and time when they expire. The rest of the parameters are usually left to the defaults.

setcookie( $name , $value, $expires, $path, $domain, $secure, $httponly );

WordPress explicitly sets these defaults for path, domain, and protocol. If these aren\'t 100% correct, the cookie just disappears. This is for security. You wouldn\'t want cookies you set on your site to be available to anyone else, otherwise someone could access your site admin and WordPress authentication would be worthless.

NOTE: Path is the base path the cookie is available from. If it\'s set to /, then it will be available to the entire site. If it\'s set to /wp-admin, only urls that start with /wp-admin will be able to access it. For example, you would not see it on your site\'s homepage.

Solution: This is a bit more complicated. Let\'s take deeper dive.

The test cookie

`wp-login.php v5.1.1

$secure = ( \'https\' === parse_url( wp_login_url(), PHP_URL_SCHEME ) );
setcookie( TEST_COOKIE, \'WP Cookie check\', 0, COOKIEPATH, COOKIE_DOMAIN, $secure );
if ( SITECOOKIEPATH != COOKIEPATH ) {
    setcookie( TEST_COOKIE, \'WP Cookie check\', 0, SITECOOKIEPATH, COOKIE_DOMAIN, $secure );
}

First, WordPress is checking your login url to see if it\'s using https or not. $secure is being used to set the cookie to respond to http or https requests, not both.

Cookie constants

Next, we have to look into some of these constants that are muddying the waters.

COOKIEPATH and SITECOOKIEPATH determine the path the cookie is available from. SITECOOKIEPATH overrides COOKIEPATH. Keep this in mind. This will be important later.

COOKIE_DOMAIN determines the domain the cookie is available from, eg yourdomains.com. If it\'s set to false, it will use the current domain.

ADMIN_COOKIE_PATH isn\'t in the source above, but will get used later. Bear with me on this one. This is the path to your WordPress dashboard.

These constants are set by WordPress, but can be changed. Let\'s take a look at the source.

/wp-includes/default-constants.php v5.1.1

if ( ! defined( \'COOKIEPATH\' ) ) {
    define( \'COOKIEPATH\', preg_replace( \'|https?://[^/]+|i\', \'\', get_option( \'home\' ) . \'/\' ) );
}

if ( ! defined( \'SITECOOKIEPATH\' ) ) {
    define( \'SITECOOKIEPATH\', preg_replace( \'|https?://[^/]+|i\', \'\', get_option( \'siteurl\' ) . \'/\' ) );
}

if ( ! defined( \'ADMIN_COOKIE_PATH\' ) ) {
    define( \'ADMIN_COOKIE_PATH\', SITECOOKIEPATH . \'wp-admin\' );
}
if ( ! defined( \'TEST_COOKIE\' ) ) {
    define( \'TEST_COOKIE\', \'wordpress_test_cookie\' );
}

Now we\'re starting to get some clarity.

COOKIEPATH uses your home url stored in your database. This is typically set in your wp-config.php file as the constant WP_HOME.

SITECOOKIEPATH overrides COOKIEPATH (remember?) and that comes from your site url stored in the database. In your wp-config.php file this is your WP_SITEURL constant.

If these don\'t match, there\'s a chance you\'ll have a problem.

This is why you see people recommend setting these with a server parameter:

define(\'WP_SITEURL\', \'https://\' . $_SERVER[\'HTTP_HOST\']);
define(\'WP_HOME\', \'https://\' . $_SERVER[\'HTTP_HOST\']);

This configuration makes sure your site responds with the correct domain. It works in most cases, but should be used cautiously.

Disclaimer: You should always do a search/replace in your database for old urls and change these to your new url. Please don\'t think the above will fix everything. It won\'t.

Debugging cookies

In order to debug this issue, try outputting these constants on your wp-login.php page like this:

add_action( \'login_init\', \'my_login_init\' );
function my_login_init() {
    echo \'<b>Cookie path:</b> \';
    var_dump( COOKIEPATH );
    echo \'<br /><b>Cookie site path:</b> \';
    var_dump( SITECOOKIEPATH );
    echo \'<br /><b>Cookie domain:</b> \';
    var_dump( COOKIE_DOMAIN );
    echo \'<br /><b>Admin cookie path:</b> \';
    var_dump( ADMIN_COOKIE_PATH );
}

This will give you a good idea of what parameters are being used to set your cookies. If these don\'t match your site\'s settings or your expectations, you need to address it to ensure your cookie is being set correctly.

You can set these explicitly in your wp-config.php file:

// False setting for the domain uses the current domain.
define(\'COOKIE_DOMAIN\', false);
// Setting to / will only work if your site is set to the root domain.
define(\'COOKIEPATH\', \'/\');
define(\'SITECOOKIEPATH\', \'/\'); 

Authorization cookies

All the above have to do with the test cookie which is the source of the error message, but there\'s one more step beyond that: your authorization cookies.

WordPress sets a bunch of cookies, depending on the context. For logging in, you\'ll need these:

  1. \'wordpress_logged_in_\' . COOKIEHASH
  2. and either \'wordpress_\' . COOKIEHASH or \'wordpress_sec_\' . COOKIEHASH

These cookies need to have the right path, protocol and domain or you won\'t be able to log in.

Fortunately, most of those checks are taken care of with the test cookie we already looked at. The only difference is with the admin path:

define( \'ADMIN_COOKIE_PATH\', SITECOOKIEPATH . \'wp-admin\' );

If the path to your admin is different than yourdomain.com/wp-admin, you need to set this in your wp-config.php file like this:

define( \'ADMIN_COOKIE_PATH\', \'/path/to/wp-admin\' );

Conclusion

This is a complicated problem. There are multiple causes for what appears to be the same issue.

If you get this error, you will have to do some debugging to find out what\'s going on. Here are some suggestions:

  1. Always check your browser first. Make sure it\'s able to save cookies from PHP.
  2. If you recently migrated, check for old urls in your database, then check your wp-config.php settings.
  3. If you moved your WordPress admin, you must set your admin path cookie in wp-config.php.
  4. Check your cookie paths, domains, and protocols to make sure they match.
  5. Make sure you\'re not sending headers prematurely.
  6. Check to make sure a caching layer like Varnish or CDN like Cloudflare allows you to set cookies and bypass cache both in the admin and through the login process.

Best of luck!

SO网友:user3725526

谢谢你的详细回答。如果您的WP站点是http,那么meesage也可以来自apache httpd中的头设置。conf.在我的例子中,在我评论了以下行之后,它就起作用了:

#Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
http网站上没有安全设置!

SO网友:Sebas Rossi

如果您确信您的用户和密码是正确的,那么您只需重新加载页面即可登录。

相关推荐

Cookies in template

我需要根据cookies只显示一次页面的某些部分。主要问题是我只能在插件中设置cookie,挂起init操作。我已经读了20页的谷歌,这个网站,问了2个论坛,但我仍然有这个问题。任何帮助都将不胜感激!