我在正在进行的Laravel 5.7项目中实现了电子邮件验证。我收到了电子邮件,但是每当我单击确认按钮甚至是电子邮件中提供的URL时,都会收到403禁止错误。
我已经搜索了几种解决方案,但未能找到解决该问题的方法。指向此错误的唯一合理的指针是此github问题https://github.com/laravel/framework/issues/25716,该问题已由Taylor Otwell合并并关闭,但该问题仍然存在。
这是我收到的电子邮件: 这是我单击电子邮件页脚上的按钮或actionUrl时抛出的错误:,这是显示403页时显示的URL https://www.mywebsite.com/email/verify/1?expires=1540140119&signature=fd7dc72b05da6f387b2f52a27bceee533b2256436f211930c1319c7a544067da
请帮助我。谢谢
编辑:仅在生产应用程序中会出现此问题。在本地,此电子邮件验证有效,但在生产(活动)服务器上抛出403。我的电子邮件服务是mailgun,除完成电子邮件验证外,我还可以访问与该应用程序相关的所有其他电子邮件内容。 我需要帮助。谢谢您的期待
答案 0 :(得分:7)
对我来说是因为手动创建验证路线。在laravel 6.x或7.x中,验证电子邮件的路由路径已更改。从/email/verify/{id}
到/email/verify/{id}/{hash}
可能仅是因为我手动使用规则,而不是Auth::routes(['verify' => true])
有关更多信息,laravel升级指南upgrade#email-verification-route-change
答案 1 :(得分:1)
如果您的应用程序在某些代理之后运行并且可能无法自行处理SSL终止,通常会发生这种情况。
解决方案是添加
protected $proxies = '*';
到TrustProxies
中间件。
答案 2 :(得分:1)
在我的情况下,原因之一可能是您已经使用普通的经过验证的用户登录,并且您单击了验证电子邮件链接。在这种情况下,它将射击403。我认为这不正常,但无论如何。
答案 3 :(得分:0)
要先使用laravel电子邮件进行验证,必须先添加路由
如果默认情况下您在Illuminate / Routing / Router.php中看到varify路由为禁用
Email Verification Routes...
if($options['verify'] ?? false)
{$this->emailVerification();
}
您必须通过true才能启用
Auth::routes(['verify'=>true]);
在您的web.php文件中。
现在使用
php artisan route:list and check it,s working
答案 4 :(得分:0)
结果是,当您的laravel应用程序在代理(apache,nginx等)后面运行时,通常会发生这种情况,因此我们最终用自己的中间件替换了laravel的默认“签名”中间件,该中间件检查https://链接。这里的StackOverFlow答案能够为我解决此问题:
Signed route for email verification does not pass signature validation
答案 5 :(得分:0)
检查VerifiedEmails特性中的verify方法, 他们在那里:
if (! hash_equals((string) $request->route('hash'), sha1($request->user()->getEmailForVerification()))) {
throw new AuthorizationException;
}
我已经转储了该变量$request->route('hash')
,它为空,因此我在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);
}
现在可以使用了!
答案 6 :(得分:0)
对我来说,问题是我的APP_URL的协议为 http ,当我单击验证链接时,NGINX会自动将URL从http重定向到 https ,这就是签名的原因验证失败。我将APP_URL更新为具有 https 协议,从而解决了我的问题。
答案 7 :(得分:0)
我个人对这个问题的经验是,我在 MAIL_DRIVER
文件中将 log
设置为 .env
,而 Laravel 在将激活链接存储在日志。
因此,当您有验证电子邮件时,切勿将 log
用于 MAIL_DRIVER
。
(我的 Laravel 版本是 5.8)。