如何在不要求用户登录Laravel的情况下验证电子邮件
我正在开发一个Laravel应用程序。我的应用程序正在使用Laravel内置的身份验证功能。在Laravel auth中,当用户注册时,将发送验证电子邮件。当用户验证电子邮件时,单击电子邮件内的链接,如果用户尚未登录,则用户必须再次登录以确认电子邮件 验证控制器如何在不要求用户登录Laravel的情况下验证电子邮件,laravel,laravel-authentication,laravel-controller,Laravel,Laravel Authentication,Laravel Controller,我正在开发一个Laravel应用程序。我的应用程序正在使用Laravel内置的身份验证功能。在Laravel auth中,当用户注册时,将发送验证电子邮件。当用户验证电子邮件时,单击电子邮件内的链接,如果用户尚未登录,则用户必须再次登录以确认电子邮件 验证控制器 类验证控制器扩展控制器 { 使用验证邮件、重定向SUSERSBASEDON角色; /** *创建一个新的控制器实例。 *@返回无效 */ 公共函数构造() { $this->middleware('auth'); $this->midd
类验证控制器扩展控制器
{
使用验证邮件、重定向SUSERSBASEDON角色;
/**
*创建一个新的控制器实例。
*@返回无效
*/
公共函数构造()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify','resend');
}
公共函数重定向路径()
{
返回$this->getRedirectTo(Auth::guard()->user());
}
}
我试着对这句话发表评论
$this->middleware('auth');
但它不起作用,反而抛出了一个错误。即使用户未登录,如何使Laravel能够验证电子邮件?首先,删除行
$this->middleware('auth')代码>,就像你做的那样
接下来,将验证邮件
特征中的验证
方法复制到您的验证控制器
,并对其进行一些更改。方法应如下所示:
public function verify(Request $request)
{
$user = User::find($request->route('id'));
if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
throw new AuthorizationException;
}
if ($user->markEmailAsVerified())
event(new Verified($user));
return redirect($this->redirectPath())->with('verified', true);
}
public function verify(\Illuminate\Http\Request $request)
{
$user = User::find($request->route('id'));
if ($request->route('id') != $user->getKey()) {
throw new AuthorizationException;
}
if ($user->markEmailAsVerified())
event(new Verified($user));
return redirect()->route('login')->with('verified', true);
}
这将覆盖验证用户
特征中的方法,并删除授权检查
安全性(如果我错了,请纠正我!)
它仍然是安全的,因为请求是经过签名和验证的。如果某人以某种方式获得了对验证电子邮件的访问权限,则可以验证其他用户的电子邮件地址,但在99%的情况下,这几乎不存在任何风险。如果您想在不登录的情况下激活用户帐户,您可以分两步完成此操作
1-删除或注释VerificationController中的身份验证中间件
示例如下:
public function __construct()
{
//$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
2-由于verify route通过{id},您只需编辑verify函数即可通过route id请求找到用户,如下代码所示:
文件路径:::\yourproject\vendor\laravel\framework\src\illumb\Foundation\Auth\VerifiesEmails.php
$user = User::findOrfail($request->route('id'));
完整示例
public function verify(Request $request)
{
$user = User::findOrfail($request->route('id'));
if (! hash_equals((string) $request->route('id'), (string) $user->getKey())) {
throw new AuthorizationException;
}
if (! hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
throw new AuthorizationException;
}
if ($user->hasVerifiedEmail()) {
return redirect($this->redirectPath())->with('verified', true);
}
if ($user->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return redirect($this->redirectPath())->with('registered', true);
}
这里有一个更适合未来的解决方案:
类验证控制器扩展控制器
{
// …
使用电子邮件{
验证为原始验证;
}
/**
*创建一个新的控制器实例。
*
*@返回无效
*/
公共函数构造()
{
$this->middleware('auth');//不要删除此
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify','resend');
}
/**
*将已验证用户的电子邮件地址标记为已验证。
*
*@param Request$Request
*@返回响应
*
*@Towns AuthorizationException
*/
公共功能验证(请求$Request)
{
$request->setUserResolver(函数()使用($request){
返回用户::findOrFail($request->route('id'));
});
返回$this->originalVerify($request);
}
}
因此,当未经验证的用户单击电子邮件确认链接时,将发生以下情况:
用户将被重定向到登录视图1
用户输入凭证;成功登录2
用户将被重定向回电子邮件确认URL
电子邮件将被标记为已确认
1此时,电子邮件将不会标记为已确认
2用户可能多次输入错误凭据。一旦他输入了正确的凭据,他将被重定向到预期的电子邮件确认URL。您不应该删除$this->middleware('auth')
,因为这会影响重定向。如果删除它,未经身份验证的用户将重定向到“/email/verify”,而不是“/login”
所以$this->中间件('auth')代码>将更改为$this->middleware('auth')->除了('verify')“验证控制器”中的代码>
同时将“验证邮件”中的“验证”功能复制到“验证控制器”中
在函数顶部添加这两行代码
$user = User::find($request->route('id'));
auth()->login($user);
因此,您以编程方式登录用户,然后执行进一步的操作,以允许对未登录(即未经验证)的用户进行电子邮件验证:
更改为:app/Http/Controllers/Auth/VerificationController.php:
$this->中间件('auth')
到$this->中间件('auth')->除了('verify')代码>
从VerifiesEmails
trait复制verify()
方法
编辑验证方法,使其在没有预期的$request->user()
数据的情况下工作
VerificationController
中我的Verification()
方法如下所示:
public function verify(Request $request)
{
$user = User::find($request->route('id'));
if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
throw new AuthorizationException;
}
if ($user->markEmailAsVerified())
event(new Verified($user));
return redirect($this->redirectPath())->with('verified', true);
}
public function verify(\Illuminate\Http\Request $request)
{
$user = User::find($request->route('id'));
if ($request->route('id') != $user->getKey()) {
throw new AuthorizationException;
}
if ($user->markEmailAsVerified())
event(new Verified($user));
return redirect()->route('login')->with('verified', true);
}
签名中间件
Laravel使用名为signed
的中间件来检查应用程序生成的URL的完整性。签名检查URL创建后是否已更改。尝试更改url中的id、过期时间或签名,会导致错误-非常有效和有用的中间件来保护verify()方法
有关更多信息:
(可选)
我将用户重定向到登录路径,而不是预定路径,原因有二。1) 登录后,它会尝试将用户重定向到电子邮件验证链接,导致错误;2) 我想使用附加到重定向的已验证的true flash数据,如果用户已成功验证其电子邮件地址,则在登录页面上显示警报
我的登录页面警报示例:
@if(session()->has('verified'))
<div class="alert alert-success">Your email address has been successfully verified.</div>
@endif
@if(session()->has('verified'))
您的电子邮件地址已成功验证。
@恩迪夫
建议
如果您对我如何改进此代码有任何建议,请联系我们