Есть ли встроенный способ убрать перечисление аккаунтов из регистрации?
Я создал новый сайт с помощью Jetstream и Inertia. В настоящее время приложение возвращает сообщение «Электронное письмо уже принято». сообщение, если пользователь пытается зарегистрироваться с существующим адресом электронной почты. Несмотря на временный анализ, я хотел бы сохранить конфиденциальность существования учетных записей пользователей. Есть ли способ сохранить уникальное ограничение для электронной почты, но отображать такое же внешнее поведение, если кто-то регистрируется с существующей электронной почтой? В идеале я хотел бы не создавать второго пользователя, а отправить электронное письмо существующему пользователю с предложением сбросить свой пароль или проигнорировать его.
2 ответа
Вот что у меня сработало:
- Создайте новое исключение проверки в
app/Exceptions/ExistingUserException.php
namespace App\Exceptions;
use Illuminate\Validation\ValidationException;
class ExistingUserException extends ValidationException
{
}
- Разбейте валидацию на 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);
}
- Создайте новое промежуточное ПО в
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;
}
}
- Внедрить промежуточное ПО во все маршруты fortify через
config/fortify.php
'middleware' => [CatchExistingUser::class, 'web'],
- Удалите промежуточное ПО аутентификации со страницы проверки, перезаписав маршрут в
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- крючок проверки