Перенаправление с 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
>> ошибка (см. скриншот)Посоветуйте, пожалуйста, как решить.
Код и конфигурация ниже. Заранее спасибо...
Другие детали:
<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>
(example.com.conf)
<VirtualHost *:80>
ServerName example.com
ServerAlias example.com
ServerAdmin support@example.com
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 support@example.com
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 support@example.com
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 support@example.com
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 / 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,
];
}
Решено. Проблема оказалась в том, что 000-default.conf
виртуальный хост все еще был активен (включен) и перехватывает такие запросы, как http://example.com/*
. Как только это было отключено с помощью:
a2dissite 000-default.conf
все заработало как положено.
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
Как и у вас дублировать. (Затем удалите дубликат.)