Laravel 5 如何检查密码重置令牌是否已过期

7

我正在使用Laravel 5开发一个Web应用程序,我使用了Laravel的make:auth脚手架。我成功发送了带有令牌的密码重置链接,并在我的端口上运作良好。在单击重置链接后,我会得到以下网址:http://example.com/password/reset/{reset_token}。现在,在我的auth.reset刀片文件中,我想首先检查{reset_token}是否已过期,因为在config.auth.php的60分钟过期时间内,似乎不会自动删除过期的令牌。所以我正在尝试使用以下方式手动检查重置令牌是否仍然有效:

function validateReminderToken($token)
{
    // I want to add some filter here like
    // if (tokenExpired($token)) return false;     
    $res = DB::table('password_resets')->where('token', $token)->get();
    if (empty($res)  || $res === null) {
        return false;
    }

    $res = $res[0];
    return $res->email;
}

我该如何做?是否有内置的方法来检查令牌是否过期?谢谢。

4个回答

10

使用created_at检查是否已经经过了从插入时间算起的某个时间段。例如,您可以像这样进行操作:

$token = DB::table('password_resets')
    ->where('token','=',$token)
    ->where('created_at','>',Carbon::now()->subHours(2))
    ->first();

然后检查令牌是否存在。


非常感谢 @Mithredate。这真的很有道理。 - Dexter Bengil
6
自5.4版本开始,该方法已经不再适用,因为令牌现在被散列存储在数据库中。 - mtpultz
1
在Laravel 5.4中,令牌现在已经被哈希。有一个未记录的接口TokenRepositoryInterface,其中有一个名为exists()的方法。实现该接口的类具有用于令牌验证的该方法。 - user991
@user777 正确。顺便问一下,你知道哪个具体类有exists()实现吗? - crabbly
1
@crabbly 我是这样做的:$reminder = Reminder::where('email', $user->email)->first(); 如果(! $reminder 或者 ! Hash::check($resetToken, $reminder->token)) { return $this->respondNotFound(); } 这里的Reminder是指用户密码重置(user_reminders),在Laravel中默认为password_resets。 - user991
显示剩余2条评论

9

要验证重置令牌是否过期,只需检查Laravel函数tokenExpired ($created_at, $token)

此函数仅执行以下操作:

return Carbon::parse($createdAt)->addSeconds($this->expires)->isPast();

例如:

$created_at = DB::table('password_resets')->first()['created_at'];
// => 2018-01-08 09:59:26

// Carbon::now();
// => 2018-01-08 11:03:05

Carbon::parse($created_at)->addSeconds(config('auth.passwords.users.expire'*60))->isPast()
// => true (with an expiration setting of 1 hour)

我在哪个类中可以找到tokenExpired函数? - Dexter Bengil
1
那个函数在供应商文件夹中,你可以在Illuminate\Auth\Passwords命名空间下的DatabaseTokenRepository类中找到它。 - Eleazar Resendez
很酷,你的回答似乎比我3年前接受的答案更相关。谢谢! - Dexter Bengil

5

在 Laravel 5.4 及以上版本中

$reminder = Reminder::where('email', $user->email)->first();

if (! $reminder or ! Hash::check($resetToken, $reminder->token)) {
    // Return 404, as Reminder was not found
    return $this->respondNotFound();
} 

其中Reminderpassword_resets的Eloquent模型(在Laravel中默认为password_resets)。


-1

另一种方法 - 是调用工匠命令 auth:clear-resets


这完全没有回答问题。OP问如何检查给定的令牌是否已过期。您提到的命令会从数据库中删除过期的令牌。 - Johnny Tisdale

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接