Framework: Invalid Signature - Email Verification - HTTPS

Created on 23 Apr 2019  路  8Comments  路  Source: laravel/framework

  • Laravel Version: 5.8.14
  • PHP Version: 7.3.4
  • Database Driver & Version: mysql 5.7

Description:

When using HTTPS, the email validation link gets invalid and returns an HTTP Error with 403 Invalid signature.. When using HTTP, everything works fine (but insecure).

PS: After enabling HTTPS every link uses HTTPS (also the one in the email).

Steps To Reproduce:

  1. Edit the file app/Providers/AppServiceProvider.php and add the following lines of code in the method boot:
if(env('FORCE_HTTPS')) {
    URL::forceScheme('https');
}
  1. Set the environment variable FORCE_HTTPS to true.
  2. Run php artisan config:cache if the changes haven't been applied.

Most helpful comment

I had a similar problem - it can be solved very easy if you use the TrustedProxy Middleware.

  1. Add URL::forceScheme('https'); to the boot method in AppServiceProvider.php

    if($this->app->environment('production'))
    {
        \URL::forceScheme('https');
    }
    
  2. Allow all like below or configure proxies as explained in the docs: https://laravel.com/docs/5.8/requests#configuring-trusted-proxies

    namespace App\Http\Middleware;

    use Illuminate\Http\Request;
    use Fideloper\Proxy\TrustProxies as Middleware;

    class TrustProxies extends Middleware
    {
    /*
    * The trusted proxies for this application.
    *
    * @var array|string
    */
    protected $proxies = '
    ';

      /**
      * The headers that should be used to detect proxies.
      *
      * @var int
      */
      protected $headers = Request::HEADER_X_FORWARDED_ALL;
    

    }

All 8 comments

You're using the env() helper outside the configuration files and then caching your config. When you cache your config, env() no longer works.

Can you try removing the condition and just setting URL::forceScheme('https');?

Closing as @36864 has given the answer - dont use env() outside of config files.

I removed the env() condition and just set URL::forceScheme('https'); but I still get the same error.

I found the issue with the help of @davidkroell. Before I was using container solutions to deploy my application (Docker and Heroku), but now I deployed it directly via Apache on a Debian system and the links are working fine (with HTTP and HTTPS).

I also didn't have to use URL::forceScheme('https'); this time to get all links replaced with HTTPS ones.

I had a similar problem - it can be solved very easy if you use the TrustedProxy Middleware.

  1. Add URL::forceScheme('https'); to the boot method in AppServiceProvider.php

    if($this->app->environment('production'))
    {
        \URL::forceScheme('https');
    }
    
  2. Allow all like below or configure proxies as explained in the docs: https://laravel.com/docs/5.8/requests#configuring-trusted-proxies

    namespace App\Http\Middleware;

    use Illuminate\Http\Request;
    use Fideloper\Proxy\TrustProxies as Middleware;

    class TrustProxies extends Middleware
    {
    /*
    * The trusted proxies for this application.
    *
    * @var array|string
    */
    protected $proxies = '
    ';

      /**
      * The headers that should be used to detect proxies.
      *
      * @var int
      */
      protected $headers = Request::HEADER_X_FORWARDED_ALL;
    

    }

This issue is mainly introduced by adding following in your code,

URL::forceScheme('https');

If you are just trying to fix SSL URL links (When SSL is terminated in your load balancer & laravel server is receiving requests on port 80), you should not above approach. Instead, use approach given by Laravel. It will take care of exact this scenario.

https://laravel.com/docs/6.x/requests#configuring-trusted-proxies

If you have to have forceScheme, use approach mentioned by @manfordbenjamin

In my case, it was the misconfiguration in NGINX

 location / {
    try_files $uri $uri/ /index.php?$query_string;
}

the $query_string was missing.

I had a similar problem - it can be solved very easy if you use the TrustedProxy Middleware.

  1. Add URL::forceScheme('https'); to the boot method in AppServiceProvider.php
    if($this->app->environment('production')) { \URL::forceScheme('https'); }
  2. Allow all like below or configure proxies as explained in the docs: https://laravel.com/docs/5.8/requests#configuring-trusted-proxies

    <?php
    
    namespace App\Http\Middleware;
    
    use Illuminate\Http\Request;
    use Fideloper\Proxy\TrustProxies as Middleware;
    
    class TrustProxies extends Middleware
    {
      /**
      * The trusted proxies for this application.
      *
      * @var array|string
      */
      protected $proxies = '*';
    
      /**
      * The headers that should be used to detect proxies.
      *
      * @var int
      */
      protected $headers = Request::HEADER_X_FORWARDED_ALL;
    }
    

Thanks man it works.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Anahkiasen picture Anahkiasen  路  3Comments

iivanov2 picture iivanov2  路  3Comments

ghost picture ghost  路  3Comments

jackmu95 picture jackmu95  路  3Comments

JamborJan picture JamborJan  路  3Comments