Laravel Redirect All Requests To HTTPS

2020-01-27 09:19发布

Our entire site is to be served over https. I have 'https' in each route. However, how do I redirect them to https if they attempt it over http?

Route::group(array('https'), function()
{
     // all of our routes
}

标签: laravel-4
15条回答
我欲成王,谁敢阻挡
2楼-- · 2020-01-27 10:00

If you have a problem, where for some reason Request::secure() returns false, even when the url is https, it could be because $_SERVER['HTTPS'] value doesn't exist.

This is a workaround:

App::before(function ($request){
    // Force https
    if(!Request::secure() && array_get($_SERVER, 'SERVER_PORT') != 443){
        return Redirect::secure(Request::path());
    }
});
查看更多
小情绪 Triste *
3楼-- · 2020-01-27 10:01

If you have to use Laravel 4 itself to handle the redirecting (like me), I'd go for the following setup (explanation as comments in the code):

Route filter:

// app/filters.php
Route::filter('ssl.force', function()
{
    if(App::environment('production') && !Request::secure())
    {
        // don't set a session cookie when redirecting to another scheme to 
        // avoid dropping the session when switching scheme
        Config::set('session.driver', 'array');
        // preserve query string while redirecting by using fullUrl()
        // instead of Redirect::secure + Request::path()
        $url = str_replace('http://', 'https://', Request::fullUrl());
        return Redirect::to($url, 302, array(), true);
    }

    // secure cookies for https
    Config::set('session.secure', Request::secure());
});

Then apply the filter as a before filter to your route or route group. eg:

// app/routes.php
Route::group(array('before' => 'ssl.force'), function () {
    // SSL routes
});
查看更多
ら.Afraid
4楼-- · 2020-01-27 10:02

I don't understand about HTTP and HTTPS in detail, so I'm sorry if this answer isn't very good.

It's my understanding that there is an issue that even when client and (client specified) server are using HTTPS, Request::secure() can return false because your application may be running on a different server, which is possibly not receiving a https request.

I'm hosting my laravel app in heroku and it seems it does that. My guess is that the primary (client specified) server is a load balancer and when the request is forwarded, it arrives at the other server as a normal HTTP request.

When such forwarding can happen, you should not just check for Request::secure() to be true. I was instructed (by someone in #laravel @ irc.freenode.com) to also check Request::server('HTTP_X_FORWARDED_PROTO') to see if it's equal to 'https'.

So if you intend to follow the other advice in here and perform a redirect in case of non-secure, try checking for this server parameter too.

查看更多
啃猪蹄的小仙女
5楼-- · 2020-01-27 10:09

Using App::before

You might be able to take advantage of the App::before() block in the app/filters.php file.

Change the block to include a simple check to see if the current request is secure, and if not, redirect it.

App::before(function($request)
{
    if( ! Request::secure())
    {
        return Redirect::secure(Request::path());
    }
});

Using Filters

Another option might be to create a filter like so. People generally store this also in app/filters.php.

Route::filter('force.ssl', function()
{
    if( ! Request::secure())
    {
        return Redirect::secure(Request::path());
    }

});

You can then enforce that new filter to any of your routes, route groups, or controllers like this.

Individual Route

Route::get('something', ['before' => 'force.ssl'], function()
{
    return "This will be forced SSL";
});

Route Group

Route::group(['before' => 'force.ssl'], function()
{
    // Routes here.
});

Controller

You'll need to do this in your controller's __construct() method.

public function __construct()
{
    $this->beforeFilter('force.ssl');
}
查看更多
We Are One
6楼-- · 2020-01-27 10:09

This worked for me in Apache 2.4

I changed .htaccess in Laravel's root folder

From <IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^(.*)$ public/$1 [L] </IfModule>

To <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteRule ^(.*)$ public/$1 [L] </IfModule>

查看更多
够拽才男人
7楼-- · 2020-01-27 10:10

Another answer might be to let your web server handle this. If you are using Apache, you can use the RedirectSSL feature to make sure all requests are going to the HTTPS version of your site, and if not redirect them. This will happen before Laravel even get's the request.

Apache RedirectSSL

If you're on NGINX, you can accomplish this by having two server blocks. One for normal HTTPS on port 80, and another for HTTPS on port 443. Then configure the normal server block to always redirect to ssl version.

server {
    listen 80;
    server_name mydomain.com;
    rewrite ^ https://$server_name$request_uri? permanent;
}

server {
    listen 443;
    server_name mydomain.com;
    ssl on;
    # other server config stuff here.
}

I'd personally go with this option as PHP itself doesn't have to process anything. It's generally cheaper to process a check like this at the web server level.

查看更多
登录 后发表回答