Php Laravel 5.6 PasswordBroker根据特定情况动态更改令牌持续时间

Php Laravel 5.6 PasswordBroker根据特定情况动态更改令牌持续时间,php,laravel,laravel-5.6,Php,Laravel,Laravel 5.6,我试图实现的是,当我们创建一个用户时,他会收到一封带有链接的登录邮件,该链接的有效期只有6个小时左右。这还不够,在大多数情况下,我们必须手动为用户设置密码 用户应有3天时间创建其第一个密码 然而,当用户点击忘记密码时,6小时的限制就足够了(因为这是他有意识地做的事情) 这是我到目前为止所拥有的 UsersController中的存储函数如下所示: public function store(StoreUser $request) { ... \DB::t

我试图实现的是,当我们创建一个用户时,他会收到一封带有链接的登录邮件,该链接的有效期只有6个小时左右。这还不够,在大多数情况下,我们必须手动为用户设置密码

用户应有3天时间创建其第一个密码

然而,当用户点击忘记密码时,6小时的限制就足够了(因为这是他有意识地做的事情)

这是我到目前为止所拥有的

UsersController中的存储函数如下所示:

public function store(StoreUser $request)
    {
        ...

        \DB::transaction(function () use ($request, $data) {

            $roles = $request->input('roles');
            $isInternal = $request->input('is_internal');
            $customers = $request->input('customers', []);

            /** @var User $user */
            $user = $this->userRepository->create($data);
            $user->assignRole($roles);

            if ($isInternal == false && !empty($customers)) {
                $user->customers()->sync($customers);
            }

            $token = app(PasswordBroker::class)->createToken($user);
            $user->notify(new AccountActivationNotification($token));
        });

        return $this->respond()->success([], "User successfully created.");
    }
我们的重置忘记功能:

    public function reset(Request $request)
    {
        $request->validate([
            'token' => 'required',
            'email' => 'required|email',
            'password' => 'required|confirmed|min:6',
        ]);

        $credentials = $request->only('email', 'password', 'password_confirmation', 'token');

        // Here we will attempt to reset the user's password. If it is successful we
        // will update the password on an actual user model and persist it to the
        // database. Otherwise we will parse the error and return the response.
        $response = $this->passwordBroker->reset(
            $credentials,
            function ($user, $password) {
                $user->password = $password;
                $user->status = StatusesService::STATUS_ACTIVE;
                $user->email_verified_at = now();
                $user->save();
                event(new PasswordReset($user));
            }
        );

        return $response == $this->passwordBroker::PASSWORD_RESET
            ? $this->respond()->success()
            : $this->respond()->validationFailed(trans($response));
    }

    public function forgot(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
        ]);

        // We will send the password reset link to this user. Once we have attempted
        // to send the link, we will examine the response then see the message we
        // need to show to the user. Finally, we'll send out a proper response.
        $response = $this->passwordBroker->sendResetLink(
            $request->only('email')
        );
        return $response == $this->passwordBroker::RESET_LINK_SENT
            ? $this->respond()->success([], "Your password has been reset, please check your inbox.")
            : $this->respond()->validationFailed(trans($response));
    }
我们已经在config/auth.php中设置了两种不同的配置:

 'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 4320, //3 days
        ],
        'users_fpassword' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 1440, //6 hours
        ],
    ],

根据本文开头描述的情况,我们可以如何在
config/auth.php
中的配置之间进行动态更改?

我想您需要的是如何在Laravel中动态设置配置值。您可以使用Laravel助手函数轻松地实现这一点

config(['auth.passwords.users.expire' => 120]);
因此,在配置文件中,将其设置为默认的6小时到期时间

 'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 1440, //6 hrs
        ],
    ],
在控制器函数中,只需添加一行

public function store(StoreUser $request)
    {
        ...

        \DB::transaction(function () use ($request, $data) {

            $roles = $request->input('roles');
            $isInternal = $request->input('is_internal');
            $customers = $request->input('customers', []);

            /** @var User $user */
            $user = $this->userRepository->create($data);
            $user->assignRole($roles);

            if ($isInternal == false && !empty($customers)) {
                $user->customers()->sync($customers);
            }

            config(['auth.passwords.users.expire' => 4320]);

            $token = app(PasswordBroker::class)->createToken($user);
            $user->notify(new AccountActivationNotification($token));
        });

        return $this->respond()->success([], "User successfully created.");
    }

我认为,更好的解决方案是:

  • 更改
    密码\u的方案通过在
    处添加类似
    expire\u的字段来重置
    表,该字段存储令牌的过期时间
  • 创建自己的
    TokenRepository
    (实现
    illumb\Auth\Passwords\TokenRepositoryInterface
    )。在它内部实现所有逻辑:在标记创建时,在字段填充
    expire\u,在标记检查时-验证它的过期时间晚于现在
  • 通过添加您自己的方法扩展
    PasswordBroker
    ,该方法允许您将新的令牌生存期传递给令牌存储库

  • 您可以在config/auth.php中添加另一个密码重置配置,如:

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    
        'invites' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 1440,
        ],
    ],
    
    这可以在以后的控制器中使用,如:

    if (!app('auth.password')->broker('invites')->tokenExists($user, $request->input('token'))) {
      return redirect()->back()->withInput();
    }
    

    好吧,根据你的需要调整一下。我在Laravel6.x上测试了它,它工作正常。

    这真的有效吗?config中的到期时间与在
    timestamp AFAIK处创建的令牌一起使用。我认为您不能用这个答案中描述的方式创建动态过期。我们正在使用配置函数在运行时更改过期时间。所以它应该可以工作。请看这里:它使用在时间戳处创建的
    以及配置中的
    过期
    。无论您在创建令牌时是否更改了配置,您都不需要在数据库令牌存储库中更新expire vaiable。所以这不应该起作用。