5

I implemented email verification in a Laravel 5.7 project I'm working on. I get the email, but whenever I click on the confirm button or even the url provided in the email, I get a 403 forbidden error.

I have searched for several solutions, but haven't been able to find one to this problem. The only reasonable pointers to this error is this github issue https://github.com/laravel/framework/issues/25716 which has been merged and closed by Taylor Otwell by still this problem persists.

Here's the email I get: enter image description here Here's the error it throws when I click on the button or the actionUrl at the email footer:enter image description here and here's the url shown when the 403 page is displayed https://www.mywebsite.com/email/verify/1?expires=1540140119&signature=fd7dc72b05da6f387b2f52a27bceee533b2256436f211930c1319c7a544067da

Please help me. Thank you

Edits: This problem occurs only in production app. On local, this email verification works but throws 403 on production(live) server. My email service is mailgun, and I can access every other email contents relating to the app except completing email verification. I need help please. Thanks in anticipation

Ehi
  • 168
  • 1
  • 2
  • 12
  • When you `php artisan route:list`, do you get the following middelware for the `verification.verify` route name: `web,auth,signed,throttle:6,1`? – emotality Oct 21 '18 at 16:07
  • Yes, I get it. I just checked again to confirm – Ehi Oct 21 '18 at 16:27
  • Hey @Ehi, did you set your `APP_URL` in your `.env` file? – rpm192 Nov 07 '18 at 11:52
  • For future me, the problem was that I was already logged in with another account in Chrome when I tried to verify the email of a new account. Logging out first account (or using another browser for the second account) fixed the problem. – Scotch Design Sep 10 '21 at 01:35

8 Answers8

15

One of the reasons that was in my case can be that you are already logged in with a normal verified user, and you have clicked on the verification email link. In that case it will shoot 403 . Which is not normal in my opinion, but whatever.

MR.GEWA
  • 833
  • 1
  • 15
  • 37
  • For your deleted [question](https://crypto.stackexchange.com/questions/76844/hash-two-strings-independent-from-the-sequence). Consider a=1, b =11 – kelalaka Jan 05 '20 at 21:38
8

For me because manually create verification route. which in laravel 6.x or 7.x The route path for verifying emails has changed. from /email/verify/{id} to /email/verify/{id}/{hash} This probably only happens because I use the rules manually, and not Auth::routes(['verify' => true]) for more information laravel upgrade guide upgrade#email-verification-route-change

Aslam H
  • 1,669
  • 4
  • 21
  • 46
3

This typically occurs if your application is running behind some proxies and probably doesn't handle SSL termination itself.

The solution is to add

protected $proxies = '*';

to the TrustProxies middleware.

Reference: https://laracasts.com/discuss/channels/laravel/hitting-403-page-when-clicking-verify-link-in-email-using-new-laravel-verification-57?page=1

Seun Matt
  • 1,660
  • 1
  • 9
  • 14
1

Turns out, this often happens when you have your laravel app running behind a proxy (apache, nginx etc.) We therefore end up replacing laravel's default 'signed' middleware with our own middleware that checks for https:// links. This StackOverFlow answer here was able to fix this problem for me:

Signed route for email verification does not pass signature validation

Tyler Mutai
  • 115
  • 2
  • 9
0

To use Laravel email verification you must first add the proper routes.

If you take a look at Illuminate/Routing/Router.php you'll see that by default the verify route is disabled.

if($options['verify'] ?? false) 
{
    $this->emailVerification();
}

To enable your verification routes add the following to your web.php

Auth::routes(['verify'=>true]);

Then run

php artisan route:list

to make sure that it's working.

Adham Zahran
  • 1,973
  • 2
  • 18
  • 35
  • `Auth::routes(['verify'=>true]);` is already added to my web.php file, so I don't think this is the problem. – Ehi Oct 21 '18 at 21:04
  • 1
    i check my projects and see same error. in auth/verifyController.php "singed middleware" check for signature . if you add some thing to your url this will fail .in my case when disable and enable this middleware problem resolved!! –  Oct 22 '18 at 08:49
0

Check the verify method inside the VerifiesEmails trait, there they have:

if (! hash_equals((string) $request->route('hash'), sha1($request->user()->getEmailForVerification()))) {
    throw new AuthorizationException;
}

I have dumped this variable $request->route('hash') and it was null, so I overrided it in the VerificationController:

    /**
 * Mark the authenticated user's email address as verified.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 * @throws \Illuminate\Auth\Access\AuthorizationException
 */
public function verify(Request $request)
{
    if (! hash_equals((string) $request->route('id'), (string) $request->user()->getKey())) {
        throw new AuthorizationException;
    }

    if (! hash_equals((string) $request->query('hash'), sha1($request->user()->getEmailForVerification()))) {
        throw new AuthorizationException;
    }

    if ($request->user()->hasVerifiedEmail()) {
        return redirect($this->redirectPath());
    }

    if ($request->user()->markEmailAsVerified()) {
        event(new Verified($request->user()));
    }

    return redirect($this->redirectPath())->with('verified', true);
}

And now it works!

0

The problem for me was my APP_URL had a protocol of http and when I clicked on the verification link NGINX automatically redirected the url from http to https that's why the signature validation failed. I updated the APP_URL to have a protocol of https and that resolved my problem.

0

My personal experience with this problem was that I set MAIL_DRIVER to log in the .env file, and Laravel escaped special characters (such as &) when it stored the activation link in the log.

So NEVER use the log for MAIL_DRIVER when you have verification email. (my Laravel version was 5.8).