'Laravel - 403 invalid signature on email verification
I have enabled Email verification on my laravel site.
If they dont do it immediatly, but after a day or two, the link times out.. and they land on a page with 403-invalid signature.
From there they cannot do anything else beside manually editing the link. this is the point where I already lost some registrations. Is there a way to:
a) make this timeout much longer
b) in case of timeout/error land on a page that actually makes sense to the user?
Solution 1:[1]
In laravel 5.8 or above add this lines to config/auth.php
'verification' => [
'expire' => 525600, // One year in minutes
],
Solution 2:[2]
@Omer YILMAZ answears your "a)" call and I am answearing your "b)" call:
We should disable signed
Middleware that validates the URL signature (expiration) and automatically shows 403 page for the verification route, and then we should create a custom logic to validate the URL signature doing whatever we would like if it is invalid (expired).
Laravel 5.7, 5.8, 6.x and 7.x
Changing Auth\VerificationController
provided by Laravel:
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\VerifiesEmails;
class VerificationController extends Controller
{
use VerifiesEmails {
verify as verifyTrait;
}
protected $redirectTo = '/';
public function __construct()
{
$this->middleware('auth');
// $this->middleware('signed')->only('verify'); <-- remove this: it is causing 403 for expired email verification URLs
$this->middleware('throttle:6,1')->only('verify');
}
public function verify(Request $request)
{
if (!$request->hasValidSignature()) {
// some custom message
}
else {
return $this->verifyTrait($request);
}
}
}
Laravel 8.x
Changing the example provided by Laravel:
use Illuminate\Foundation\Auth\EmailVerificationRequest;
use Illuminate\Http\Request;
Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
if (!$request->hasValidSignature()) {
// some custom message
}
else {
$request->fulfill();
return redirect('/home');
}
})->middleware(['auth', /*'signed' <-- remove this*/])->name('verification.verify');
Solution 3:[3]
The following solution worked for me. Go to the next folder, app/Http/Middleware, and edit the following file TrustProxies.php. Change protected $proxies
; edit for the following protected $proxies = ‘*’;
namespace App\Http\Middleware;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
protected $proxies = '*';
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Omer YILMAZ |
Solution 2 | |
Solution 3 | Karl Hill |