Есть ли встроенный способ убрать перечисление аккаунтов из регистрации?

Я создал новый сайт с помощью Jetstream и Inertia. В настоящее время приложение возвращает сообщение «Электронное письмо уже принято». сообщение, если пользователь пытается зарегистрироваться с существующим адресом электронной почты. Несмотря на временный анализ, я хотел бы сохранить конфиденциальность существования учетных записей пользователей. Есть ли способ сохранить уникальное ограничение для электронной почты, но отображать такое же внешнее поведение, если кто-то регистрируется с существующей электронной почтой? В идеале я хотел бы не создавать второго пользователя, а отправить электронное письмо существующему пользователю с предложением сбросить свой пароль или проигнорировать его.

2 ответа

Вот что у меня сработало:

  1. Создайте новое исключение проверки в app/Exceptions/ExistingUserException.php
      namespace App\Exceptions;

use Illuminate\Validation\ValidationException;

class ExistingUserException extends ValidationException
{

}
  1. Разбейте валидацию на 2 этапа app/Actions/Fortify/CreateNewUser.php, бросая расширенный ValidationException если форма в остальном хорошая
              Validator::make($input, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255'],
            'password' => $this->passwordRules(),
            'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['required', 'accepted'] : '',
        ])->validate();

        $validator =  Validator::make($input, [
            'email' => ['unique:users'],
        ], ['email.unique'=>'']);

        if ($validator->fails())
        {
            throw new ExistingUserException($validator);
        }
  1. Создайте новое промежуточное ПО в app/Http/Middleware/CatchExistingUser.php
      <?php

namespace App\Http\Middleware;

use App\Exceptions\ExistingUserException;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\URL;

class CatchExistingUser
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next, $redirectToRoute = null)
    {
        $response = $next($request);

        if ($response->exception && $response->exception instanceof ExistingUserException)
        {
            return $request->expectsJson()
                    ? abort(403, 'Your email address is not verified.')
                    : Redirect::guest(URL::route($redirectToRoute ?: 'verification.notice'));
        }

        return $response;
    }
}
  1. Внедрить промежуточное ПО во все маршруты fortify через config/fortify.php
      'middleware' => [CatchExistingUser::class, 'web'],
  1. Удалите промежуточное ПО аутентификации со страницы проверки, перезаписав маршрут в routes/web.php
      use Illuminate\Http\Request;
use Laravel\Fortify\Contracts\VerifyEmailViewResponse;
...
Route::get('/email/verify', function (Request $request) {
    $user = $request->user();
    if ($user && $user->hasVerifiedEmail())
    {
        return redirect()->intended(config('fortify.home'));
    }
    return app(VerifyEmailViewResponse::class);
})
->name('verification.notice');

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

Я согласен с Unflux не изменять это, но если вам нужно, вы можете изменить CreateNewUser.php расположен на app\Actions\Fortify\CreateNewUser.php и изменить сообщение проверки или изменить процесс.

В create() метод, отвечающий за создание нового пользователя, выглядит так:

      public function create(array $input)
    {
        //define custom messages
        $customValidationMessages = {
            'email.unique' => 'New Message',
        }


        Validator::make($input, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], //email validation rules here
            'password' => $this->passwordRules(),
        ], $customValidationMessages)->validate(); //add the variable containing the custom message(s) here

        
        return User::create([
            'name' => $input['name'],
            'email' => $input['email'],
            'password' => Hash::make($input['password']),
            'api_token' => Str::random(60),
        ]);
    }

Если вам нужно отправить пользователю электронное письмо или настроить его дополнительно, я предлагаю вам изучить возможность реализации «After Validation Hook», о которой вы можете прочитать здесь: https://laravel.com/docs/8.x/validation#after- крючок проверки

Другие вопросы по тегам