Настройка регистрации в Laravel

Регистрация в Laravel

У Laravel отличная система аутентификации «из коробки». С помощью всего нескольких команд вы получить готовый функционал для логина и регистрации. Но давайте погрузимся глубже и посмотрим, что мы еще можем настроить.

1. Отключение регистрации

Что если в вашем приложении только предварительная регистрация или только через администратора?

Начиная с Laravel 5.7, все, что вам нужно сделать для её отключения, это добавить параметр в router/web.php:

Auth::routes(['register' => false]);

Теперь больше нет ссылки «Регистрация» в правом верхнем углу, а маршрут /register покажет 404-ую страницу.

2. Включение подтверждения по электронной почте

Еще одна новая функция Laravel 5.7 — верификация электронной почты с полем users.email_verified_at в базе данных. По умолчанию она отключена, но все необходимые поля и маршруты генерируются, просто скрыты.

Чтобы включить эту функцию, просто передайте параметр в routs/web.php:

Auth::routes(['verify' => true]);

Кроме этого, обязательно запустите php artisan make:auth, чтобы он генерировал необходимые шаблоны, чтобы было что показывать пользователям после того, как они кликнут на проверочную ссылку.

Наконец, если вам нужны маршруты, доступные только для уже проверенных пользователей, используйте верификационные мидлвары (middleware):

Route::get('profile', function () {
    // Только проверенные пользователи смогу войти в профиль...
})->middleware('verified');

 

3. Отключение сброса пароля

По умолчанию команда php artisan make:auth генерирует bootstrap’ные страницы для логина и регистрации, в том числе и для сброса забытого пароля.

Но если вы хотите отключить эту функцию и использовать какой-либо другой механизм для их восстановления, то в routes/web.php есть еще один параметр:

Auth::routes(['reset' => false]);

Примечание: вы можете скомбинировать это с предыдущими советами по регистрации и проверке, и сделать в routes/web.php так:

Auth::routes([
  'register' => false,
  'verify' => true,
  'reset' => false
]);

Ниже перечислены действующие маршруты из vendor/laravel/framework/src/Illuminate/Routing/Router.php:

public function auth(array $options = [])
{
    // Authentication Routes...
    $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
    $this->post('login', 'Auth\LoginController@login');
    $this->post('logout', 'Auth\LoginController@logout')->name('logout');

    // Registration Routes...
    if ($options['register'] ?? true) {
        $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
        $this->post('register', 'Auth\RegisterController@register');
    }

    // Password Reset Routes...
    if ($options['reset'] ?? true) {
        $this->resetPassword();
    }

    // Email Verification Routes...
    if ($options['verify'] ?? false) {
        $this->emailVerification();
    }
}

 

4. Перенаправление после регистрации

По умолчанию свежезарегистрированные пользователи перенаправляются на адрес /home. Возможно, вы захотите изменить его, это делается в файле app/Http/Controllers/Auth/RegisterController.php:

class RegisterController extends Controller
{
    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = '/home';

Просто измените этот параметр, и все.

Но если у вас более сложная логика, чем просто один статический адрес? Например, вам нужны разные редиректы, в зависимости от роли нового пользователя. Тогда вы можете создать отдельный метод в этом же классе RegisterController с именем redirectTo():

protected function redirectTo()
{
    if (auth()->user()->role_id == 1) {
        return '/admin';
    }
    return '/home';
}

Поведение метода переопределит значение свойства $redirectTo, даже если оно уже присутствует.

 

5. Изменение правил валидации полей

По умолчанию Auth имеет четыре поля:

  • name
  • email
  • password
  • confirm password

Все они обязательны, и эти правила проверки указаны в том же app/Http/Controllers/Auth/RegisterController.php:

protected function validator(array $data)
{
    return Validator::make($data, [
        'name' => ['required', 'string', 'max:255'],
        'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
        'password' => ['required', 'string', 'min:6', 'confirmed'],
    ]);
}

Соответственно, если вы захотите изменить любое из них, например, добавить более сложные требования к паролю, чем минимум в 6 символов,
то просто отредактируйте этот метод validator().

 

6. Отключение автоматического входа после регистрации

Другое поведение по умолчанию, которое вы можете изменить, это автоматический вход сразу после регистрации. Вы можете перенаправить пользователя на отдельную страницу «Успешно», подразумевая, что он может войти в систему позже.

Для этого вам нужно переопределить метод register() трейта RegistersUsers.

Контроллер, который мы обсуждали выше, RegisterController, использует этот важный трейт:

class RegisterController extends Controller
{
    use RegistersUsers;
    // ... all other code of controller

Эта трейт выполняет всю «грязную работу» регистрации. Он является частью ядра фреймворка и расположен в vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers.php:

trait RegistersUsers
{
    /**
     * Handle a registration request for the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $this->validator($request->all())->validate();

        event(new Registered($user = $this->create($request->all())));

        $this->guard()->login($user);

        return $this->registered($request, $user)
                        ?: redirect($this->redirectPath());
    }

    // ... A few other methods

}

Чтобы отключить автоматический вход, вам нужно удалить эту строку:

$this->guard()->login($user);

Но вы не можете напрямую редактировать ядро Laravel или что-либо из того, что находится внутри папки /vendor. Что вы можете сделать, так это переопределить этот метод и поместить его в свой RegisterController, например так:

namespace App\Http\Controllers\Auth;

// НЕ ЗАБУДЬТЕ ДОБАВИТЬ ЭТИ ДВА!
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;

use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

class RegisterController extends Controller
{

    // ... Other methods

    /**
     * Handle a registration request for the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $this->validator($request->all())->validate();

        event(new Registered($user = $this->create($request->all())));

        return $this->registered($request, $user)
            ?: redirect($this->redirectPath());
    }

}

Не забудьте о параметре или методе redirectTo, как рассказно в предыдущем разделе, чтобы ваш зарегистрированный пользователь попадал на правильную страницу.

 

7. Добавление дополнительных полей в регистрационную форму

Наиболее типичным примером этого является добавление поля «Фамилия» в дополнение к дефолтному «Имя». Здесь нужно будет сделать несколько шагов:

Шаг 1. Добавьте поле в базу данных.

Просто добавьте эту строку в файл миграции: $table->string(‘surname’);
Выберите для редактирования существующий дефотный файл миграции или создайте новый с помощью
php artisan make:migration add_surname_to_users_table

Шаг 2. Добавьте поле как заполняемое (fillable) в модели User.

По умолчанию в app/User.php так:

protected $fillable = [
    'name', 'email', 'password',
];

Вам нужно добавить поле «surname» в этот массив.

Шаг 3. Добавьте поле в шаблон формы.

Вам необходимо отредактировать файл resources/views/auth/register.blade.php и добавить еще одно поле, возможно, просто скопировав-вставив весь код поля «name» и изменив некоторые его части.

<div class="form-group row">
    <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>

    <div class="col-md-6">
        <input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required autofocus>

        @if ($errors->has('name'))
            <span class="invalid-feedback" role="alert">
                <strong>{{ $errors->first('name') }}</strong>
            </span>
        @endif
    </div>
</div>

Шаг 4. Измените метод create().

Вот как выглядит дефолтный метод в RegisterController:

protected function create(array $data)
{
    return User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
    ]);
}

Догадались? Да, вам просто нужно добавить еще одну строку, с фамилией, поэтому окончательный результат таков:

protected function create(array $data)
{
    return User::create([
        'name' => $data['name'],
        'surname' => $data['surname'],
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
    ]);
}

 

8. Логин через имя пользователя вместо почты

По умолчанию электронная почта является наиболее важным полем для пользователя, именно она используется в качестве уникального идентификатора и является частью учетных данных. Но что, если в вашем случае электронная почта — это просто информационное поле, а действительные учетные данные для входа например, имя пользователя?

Во-первых, позаботьтесь о добавлении этого поля в базу данных/модели/шаблона, как показано в предыдущем разделе.

Далее, вам нужно взглянуть на app/Http/Controllers/Auth/LoginController, а именно на один трейт:

class LoginController extends Controller
{
    use AuthenticatesUsers;
    // ... All other code

Если вы углубитесь в этот трейт /vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php, то увидите один метод:

/**
 * Get the login username to be used by the controller.
 *
 * @return string
 */
public function username()
{
    return 'email';
}

Видите, это просто поле, возвращаемое функцией. И затем оно используется в валидации и аутентификации, в этом же трейте:

protected function validateLogin(Request $request)
{
    $request->validate([
        $this->username() => 'required|string',
        'password' => 'required|string',
    ]);
}

Поэтому все, что вам нужно сделать, это переопределить этот метод в вашем LoginController, аналогично тому, как мы делали с параметром redirectTo ранее в этой статье.

class LoginController extends Controller
{
    use AuthenticatesUsers;
    // ... All other code

    public function username()
    {
        return 'username';
    }
}

 

Автор: Povilas Korop
Перевод: Demiurge Ash