通过wp-config.php正确地强制WordPress使用SSL

22

如果我编辑 wp-config.php,我应该添加:

define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);

然而,我的网站有.htaccess规则,强制在整个网站上使用https和www:

Options +FollowSymlinks
RewriteEngine On
RewriteCond %{SERVER_PORT} 80 [OR]
RewriteCond %{HTTP_HOST} ^website.com
RewriteRule ^(.*)$ https://www.website.com/$1 [L,R=301]

我知道还有其他的重写规则可用,但我不确定哪一个是正确的。

以下三种重写规则中,我应该在wp-config.php中使用哪一种?

1 - 不使用isset(),使用花括号,使用server_port

if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
    $_SERVER['HTTPS'] = 'on';
    $_SERVER['SERVER_PORT'] = 443;
}

2 - 没有花括号和server_port怎么办?

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
    $_SERVER['HTTPS'] = 'on';

3 - 花括号是否必要/更好或“更正确”,server_port是否必需?

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
    $_SERVER['HTTPS'] = 'on';
    $_SERVER['SERVER_PORT'] = 443;
}

我在互联网上找到了几个关于WordPress SSL的略有不同的变体,但我无法弄清哪个是正确/主要的...


5
如果你已经通过Apache的重定向规则强制启用了SSL,我不确定你想要实现什么目标。 - Gustavo Straube
1
@GustavoStraube 似乎在代理后面。如果是这种情况,问题应该被修改。 - h0tw1r3
6个回答

15

在这种情况下,PHP代码根本不需要处理SSL。这里应用经典的SoC原则:如果你的代码没有明确地处理连接(在WP中并没有),你应该把协议检查交给Web服务器。

你还应该避免在重写规则中定义端口。如果你没有使用多站点WP设置,可以尝试:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

2
如果使用多站点呢? - T.Todua

12

我用了这个。可以继续使用。

if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
   $_SERVER['HTTPS']='on';

如果您的服务器端口与443不同,您可以指定它。否则,无需再次使用它。


这段代码应该放在哪里?我把它添加到functions.php中,现在wp-admin无法工作,但前端仍然可以正常工作。 - nu everest
2
@NuEverest,请尝试将其放置在 wp-config.php 中。 - Dmitry Gamolin
对于AWS LightSail Wordpress镜像,我们使用LightSail LoadBalancer处理TLS,Wordpress只提供HTTP服务。请注意页面缓存中的FQDN。/bitnami/wordpress/wp-config.phpif ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { define( 'WP_HOME', 'https://' . $_SERVER['HTTP_HOST'] . '/' ); define( 'WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST'] . '/' ); } else { define( 'WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/' ); define( 'WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/' ); } - jwmullally
谢谢,但请在第一行写上“===”,并加上括号,这样对于新手来说就不会太混乱了。他们通常在复制粘贴代码时不会很好地缩进。另外,请在答案中提到它应该放在 wp-config.php 文件中。由于编辑队列已满,现在我无法执行此操作。 - Valerio Bozz

5

已更正的.htaccess规则(详见wiki.apache.org):

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://mysslcertdomainname.com/$1 [R,L]

通常情况下,在Wordpress中,你不需要像(1,2,3)这样的代码范例。但是根据问题描述,似乎你使用了某种基于代理的方式。
  1. 不好 如果Web服务器没有设置HTTP_X_FORWARDED_PROTO,会生成PHP警告(标准php配置)。
  2. 在检查值之前先检查变量是否存在。不会生成警告。
  3. 很好 最佳实践**

** 通常情况下不建议更改_SERVER变量(如SERVER_PORTHTTPS),除非你有一种不常见的设置(例如在代理后面 - 这是任何此代码的原因)。


你的 .htaccess 规则中唯一的问题是它没有强制使用 www,而我发布的规则同时强制使用 www 和 https。**(这也是一个问题,因为我不确定)** - Ryflex
@Ryflex mysslcertdomainname.com 是一个例子。对于我的网站,我使用 %{SERVER_NAME} - 这意味着“重定向到在Apache中配置的主服务器名称”。这实际上取决于您购买的SSL证书中有哪些域名。 - h0tw1r3
我只想强制在每个子域名/主域名上都使用www,并且仅在主域名上使用https,在强制使用www之后,网站www.website.com将变为https://www.website.com,但www.testing.website.com将变为http://www.testing.website.com - Ryflex

3

如果您正在使用Docker,并且想要避免手动配置(由人完成),那么以下方法适用:

if ( getenv('ENABLE_HTTPS')  === "true" ) {
  define( 'FORCE_SSL_ADMIN', true );
  $_SERVER['HTTPS']='on';
}

我只需要传递一个新的变量 ENABLE_HTTPS

docker run -d --name wordpress -it --rm -p 80:80 \
-e DB_HOST=10.10.10.10:3306 \
-e DB_USER=root \
-e DB_PASSWORD=secret \
-e DB_NAME=wordpress \
-e AUTH_KEY=$RANDOM_KEY \
-e SECURE_AUTH_KEY=$RANDOM_KEY \
-e NONCE_KEY=$RANDOM_KEY \
-e LOGGED_IN_KEY=$RANDOM_KEY \
-e AUTH_SALT=$RANDOM_KEY \
-e SECURE_AUTH_SALT=$RANDOM_KEY \
-e LOGGED_IN_SALT=$RANDOM_KEY \
-e NONCE_SALT=$RANDOM_KEY \
-e WP_DEBUG=true \
-e DISABLE_WP_CRON=true \
-e ENABLE_HTTPS=true wordpress:5.7.2

2

在functions.php文件中使用以下代码:

add_action('template_redirect', 'f_force_ssl');

function f_force_ssl()
{
    if (!is_ssl()) 
    {
        wp_redirect('https://' . $_SERVER['HTTP_HOST'] . 
        $_SERVER['REQUEST_URI'], 301);
        exit();
    }
}

0
为了让这对我起作用,我必须注释掉围绕$_SERVER['HTTPS']='on';的if语句行。
我正在使用Zevenet CE 5.9,它不提供x-forwarded-for或x-forwarded-proto选项,因此为了将其放在反向代理后面,我们只需通过这种方式强制使用https :)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接