HTTPS 重定向对某些 URL 失败,但对其他 URL 成功

HTTPS 重定向对某些 URL 失败,但对其他 URL 成功

从 HTTP 重定向到 HTTPS正确地当 URL 为以下任一类型时:

  • http://example.com>> https://example.com[确定]
  • http://www.example.com>> https://example.com[确定]
  • http://www.example.com/login>> https://example.com/login[确定]

但是重定向到 HTTPS失败当 URL 如下时:

  • http://example.com/login>> 错误(见截图)

错误截图

请指教如何解决。

下面是代码和配置。提前谢谢您...

其他详情:

  • Ubuntu 16.04
  • Apache 2.4
  • mod_rewrite 已启用
  • Laravel 5.3
  • 清除浏览器缓存

.htaccess 文件

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Allow Blog in Sub-Directory
    RewriteCond $1 !^(blog)

    #Redirect to non-WWW
    RewriteCond %{HTTP_HOST} ^www.example.com$
    RewriteRule ^(.*) https://example.com/$1  [QSA,L,R=301]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]


</IfModule>

虚拟主机配置

(例如.com.conf)

<VirtualHost *:80>
        ServerName example.com
        ServerAlias example.com
        ServerAdmin [email protected]
        DocumentRoot /var/www/example.com_dev/public
        <Directory "/var/www/example.com_dev/public">
                DirectoryIndex index.php
                AllowOverride All
                Order allow,deny
                Allow from all
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<VirtualHost *:80>
        ServerName example.com
        ServerAlias www.example.com
        ServerAdmin [email protected]
        DocumentRoot /var/www/example.com_dev/public
        <Directory "/var/www/example.com_dev/public">
                DirectoryIndex index.php
                AllowOverride All
                Order allow,deny
                Allow from all
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

虚拟主机配置

(例如-ssl.com.conf)

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
    ServerAdmin [email protected]
        ServerName example.com
        ServerAlias example.com
        DocumentRoot /var/www/example.com_dev/public
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCertificateFile /etc/apache2/ssl/example_com.crt
        SSLCertificateKeyFile /etc/apache2/ssl/example_com.key
        SSLCertificateChainFile /etc/apache2/ssl/example_com.ca-bundle
        <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
            SSLOptions +StdEnvVars
        </Directory>
        <Directory "/var/www/example.com_dev/public">
            DirectoryIndex index.php
            AllowOverride All
            Order allow,deny
            Allow from all
        </Directory>
        BrowserMatch "MSIE [2-6]" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
    </VirtualHost>
</IfModule>

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
    ServerAdmin [email protected]
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/example.com_dev/public
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCertificateFile /etc/apache2/ssl/example_com.crt
        SSLCertificateKeyFile /etc/apache2/ssl/example_com.key
        SSLCertificateChainFile /etc/apache2/ssl/example_com.ca-bundle
        <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
            SSLOptions +StdEnvVars
        </Directory>
        <Directory "/var/www/example.com_dev/public">
            DirectoryIndex index.php
            AllowOverride All
            Order allow,deny
            Allow from all
        </Directory>
        BrowserMatch "MSIE [2-6]" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
    </VirtualHost>
</IfModule>

// 应用程序级重定向

(应用程序/Http/middleware/HttpsProtocol.php-Laravel 5.3)

<?php

namespace App\Http\Middleware;

use Closure;

class HttpsProtocol
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if(!$request->secure()){
            return redirect()->secure($request->getRequestUri());
        }

        return $next($request);
    }
}

应用程序级 HTTP 内核

(应用程序/Http/Kernel.php-Laravel 5.3)

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\HttpsProtocol::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    ];
}

答案1

解决了。​​问题原来是000-default.conf虚拟主机仍然处于活动状态(启用),并拦截了类似 的请求http://example.com/*。禁用后,使用:

a2dissite 000-default.conf 

一切都开始按照预期进行。

答案2

  • http://example.com>> https://example.com[确定]
  • http://example.com/login>> 错误(见截图)

从您的代码转储中我实际上看不出这两种情况是如何处理的(尽管您说第一种情况可以正常进行)?

由于您似乎正在执行 www 重定向.htaccess

#Redirect to non-WWW
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule ^(.*) https://example.com/$1  [QSA,L,R=301]

然后您可以尝试将其更改为:

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com
RewriteRule (.*) https://example.com/$1  [R=301,L]

这包括对 HTTP 的检查。因此,如果 HTTP或者 www然后重定向到 HTTPS没有 www

您需要在测试之前清除所有缓存,因为错误的 301 会被浏览器严重缓存。


您似乎已为端口 80 和 443 复制了两个虚拟主机?这可能是导致您出现问题的原因。您只需VirtualHost为端口 80 复制一个虚拟主机,为端口 443 复制一个虚拟主机:

ServerName example.com
ServerAlias example.com

应该:

ServerName example.com
ServerAlias www.example.com

就像你对复制。(然后删除重复项。)

相关内容