How do I configure SSL with Laravel 5 behind a loa

2019-04-06 09:15发布

I have a laravel 5 project deployed to AWS EC2 web instances, behind an ELB with ssl termination.

For things like assets, Laravel by default uses whatever scheme is currently used. However, I've noticed since the https traffic is decrypted by the ELB and forwarded to the EC2 nodes via http, Laravel does not think it's currently using https and thus uses http for assets. This is obviously causing problems.

From what I've found, Laravel checks for this sort of proxy setup using the X_FORWARDED_PROTO header. However I've found this header doesn't exist and instead there is an HTTP_X_FORWARDED_PROTO header. In researching this, I've found that prepending "HTTP_" is something php does. If that's true, then why isn't Laravel checking for it, as it is a purely php framework?

I've read articles saying to use something like Fideloper's Trusted Proxies, yet it's unclear why Laravel doesn't check for these headers by default.

How can I configure Laravel to accept HTTP_X_FORWARDED_* headers, or otherwise configure it to know my current scheme is https?

1条回答
Melony?
2楼-- · 2019-04-06 09:38

Laravel doesn't check for these by default because these headers can be trivially injected into a request (i.e. faked), and that creates a theoretical attack vector into your application. A malicious user can make Laravel think a request is, or is not secure, which in turn might lead to something being compromised.

When I ran into this same problem a few months back using Laravel 4.2, my solution was to create a custom request class and tell Laravel to use it her

#File: bootstrap/start.php
//for custom secure behavior -- laravel autoloader doesn't seem here yet?
require_once realpath(__DIR__) . 'path/to/my/MyCustomRequest.php';

Illuminate\Foundation\Application::requestClass('MyCustomRequest');

and then in MyCustomReuqestClass, I extended the base request class and added extra is/is-not secure logic

class Request extends \Illuminate\Http\Request
{
    /**
     * Determine if the request is over HTTPS, or was sent over HTTPS
     * via the load balancer
     *
     * @return bool
     */
    public function secure()
    {        
        $secure = parent::secure();
        //extra custom logic to determine if something is, or is not, secure
        //...
        return $secure;
    }    

    public function isSecure()
    {

        return $this->secure();
    }
}

I would not do this now. After working with the framework for a few months, I realized that Laravel's request class has the Symfony request class as a parent, meaning a Laravel request inherits a Symfony request object's behavior.

That means you can tell Laravel which proxy servers it should trust with something like this

Request::setTrustedProxies(array(
    '192.168.1.52' // IP address of your proxy server
));

This code tells Laravel which proxy servers it should trust. After that, it should pickup the standard "forwarded for" headers. You can read more about this functionality in the Symfony docs.

查看更多
登录 后发表回答