Как реализовать ForgotPasswordController в приложении SPA с Laravel / Sanctum?

Я использую Laravel 7.x и sanctum. Логины работают, и я хотел бы создать опцию «Забыли пароль» в моем приложении SPA.

Я борюсь с основами, поскольку большинство примеров в документации полагаются на леса авторизации. Пока мне удалось получить следующее:

  • У меня есть класс контроллера ForgotPasswordController с методом reset, который получает электронное письмо для сброса через POST.
  • Я создал объект: $user = User::where('email', $email)->get()->first();

На данный момент я слишком незнаком с архитектурой, чтобы знать, что делать дальше, будь то фасад пароля, я вижу некоторые дополнительные классы в пространстве имен Illuminat\Auth\Password. Моя цель - создать токен с истекающим сроком действия, отправить его пользователю по электронной почте через конфигурацию электронной почты по умолчанию (я знаю, как отправить электронное письмо / создать шаблон), а затем иметь возможность выполнить вызов веб-службы, который позволит разрешить пароль.

Вот что я знаю ...

  • Я установил черту CanResetPassword для своих пользовательских моделей, которая, как мне кажется, необходима для поддержки собственных методов сброса пароля.
  • Я считаю, что цель состоит в том, чтобы создать токен сброса, привязанный к электронной почте пользователя, срок действия которой истекает через определенный период времени, а затем отправить этот токен, добавленный к URL-адресу в электронном письме (Я не знаю архитектурных последствий, связанных с генерацией токен за строкой таблицы)
  • Есть Password фасад с sendResetLink методом, но этот метод не может работать для спа-приложений, потому что базовый URL-адрес клиентского приложения будет другим, поэтому я предполагаю, что что-то родное придется переписать. Фактически, вызов этого метода вернет ошибку Route [password.reset] not defined.

Я предполагаю, что мне понадобится пароль Facade, если да, то каков метод создания токена? Следует ли мне просто отправить ссылку с добавленным токеном по электронной почте или существуют другие архитектурные соображения для поддержки истечения срока действия токена?

Прошу прощения, если мои вопросы ошибочны, я не понимаю архитектуру, поэтому делаю предположения.


person Shane    schedule 05.07.2020    source источник


Ответы (2)


Вы пробовали аутентификацию в Laravel? Все требования к аутентификации перенесены в пакет под названием laravel/ui.

Установив этот пакет, вы можете использовать аутентификацию Laravel. Он позаботится о вашей регистрации, входе в систему и забытом пароле.

Этот пакет создаст несколько контроллеров для всех этих процессов, и те, которые вам понадобятся для забытого пароля:

  • ForgotPasswordController: будет генерировать и отправлять ссылки для сброса пароля.
  • ResetPasswordController: сбросит пароль, получив адрес электронной почты пользователя, новый пароль и токен сброса пароля.

Но если вы не хотите использовать официальный пакет Laravel, вам следует предпринять следующие шаги:

  1. Покажите пользователю форму запроса сброса пароля.
  2. Подтвердите предоставленный пользователем адрес электронной почты.
  3. Создайте токен случайного сброса пароля и сохраните его в БД (нужна таблица как минимум с двумя полями: email и token).
  4. Отправьте этот токен пользователю (лучше, если вы отправите его как параметр URL-адреса в ссылке для сброса пароля).
  5. Когда пользователь перешел на страницу сброса пароля, снова запросите электронную почту и подтвердите токен, проверив свою таблицу БД и сопоставив адрес электронной почты и токен.
  6. Сбросьте пароль на любой, какой хочет пользователь на этом этапе.

Обновление: я использую этот фрагмент кода для генерации случайных токенов:

$email = '[email protected]';
$token = \Illuminate\Support\Str::random(10);

while(\DB::table('reset_password_tokens')->where('token', $token)->exists()) {
    $token = \Illuminate\Support\Str::random(10);
}

\DB::table('reset_password_tokens')->insert(compact('email', 'token'));
person Amir H    schedule 06.07.2020
comment
Это подход, на котором я остановился, и я не уверен, как это сделать, так это сгенерировать фактический токен через архитектуру Laravel. Если вы это знаете, не могли бы вы включить это в свой ответ? - person Shane; 06.07.2020
comment
@Shane Я обновил свой ответ и добавил фрагмент кода. Надеюсь, у вас это сработает. - person Amir H; 03.01.2021

Чтобы сгенерировать токен при использовании SPA, вы должны сделать что-то вроде следующего:

const crypto = require('crypto')
crypto.randomBytes(20, (err, buffer) => {
    var token = buffer.toString('hex')
    console.log(token)

    let url = 'password/email'
    axios.post(url, {
        token: token,
        email: this.resetEmail
    })
    .then((res) => {
        console.log(res)
    }, (err) => {
        this.has_error = true
        let errorResp = err.response.data
        if (errorResp.errors.email) {
            console.log(errorResp.errors.email[0])
        }
    })
})
person dmotors    schedule 15.11.2020