Laravel 5.2. Раздельные сообщения об ошибках аутентификации

В Laravel 5 по умолчанию встроена поддержка аутентификации пользователей. Если пользователь вводит неправильные данные для входа, то максимум, что он может — это получить сообщение об ошибке: «These credentials do not match our records». Поэтому поводу могут возникнуть два вопроса: как сделать вывод на русском языке и как разделить сообщение об ошибке ввода для логина и пароля? Рассмотрим решение.

Метод login отвечающий за вход находится в трейте \vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php. Этот метод использует метод sendFailedLoginResponse для вывода сообщения об ошибке. Для формирования сообщения в методе используется метод getFailedLoginMessage.

Первое, что нам требуется — это добавить  русскую локализацию. В конфиге \config\app.php меняем локализацию по умолчанию на русскую:

'locale' => 'ru'

Создаем в папке \resources\lang папку \ru и копируем в нее файл auth.php из папки \resources\lang\en. В файл \resources\lang\ru\auth.php  добавляем два ключа:

'failedLogin' => 'Указан несуществующий email.',
'failedPassword' => 'Указан неправильный пароль.'

Вместо ‘ru’ вы можете использовать любое другое название, главное, что оно должно быть одинаковым в конфиге и в названии папки, то есть, если прописываем, например, ‘rus’, то и папка должны быть ‘rus’.

В контроллере \app\Http\Controllers\Auth\AuthController.php, использующем трейт AuthenticatesUsers.php, создадим свои методы для указания ошибок входа. Для этого подключим фасад Lang и переопределим метод getFailedLoginMessage и добавим метод getFailedPasswordMessage:

     use Illuminate\Support\Facades\Lang;
     /**
     * создадим свои методы для указания ошибок входа
     * 
     * @param \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    protected function getFailedLoginMessage()
    {
        return Lang::get('auth.failedLogin');
    }
    protected function getFailedPasswordMessage()
    {
        return Lang::get('auth.failedPassword');
    }

Заключительный штрих — переопределяем метод sendFailedLoginResponse, где делаем собственную проверку соответствия логина и пароля и на основании нее выводим в случае необходимости сообщение об ошибке:

     /**
     * переопределим метод трейта AuthenticatesUsers для определения, какое конкретно поле неправильно введено
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    protected function sendFailedLoginResponse(Request $request)
    {
        $error;
        // $fieldUser - по дефолту это поле 'email'
        $fieldUser = $this->loginUsername();
        $user = User::select($fieldUser,'password')->where($fieldUser, $request->input($fieldUser))->first();
        if (!$user || $user->email != $request->input($fieldUser)) {
            $error = [$fieldUser=>$this->getFailedLoginMessage()];
        }
        elseif ($user->password != bcrypt($request->input('password'))) {
            $error = ['password'=>$this->getFailedPasswordMessage()];
        }

        return redirect()->back()
            ->withInput($request->only($fieldUser, 'remember'))
            ->withErrors($error);
    }

Теперь в шаблоне мы можем выводить свои сообщения об ошибке ввода логина или пароля:

<form method="post" action="login" class="form-signin">
  <h2 class="form-signin-heading">Войти</h2>
  <label for="inputEmail" class="sr-only">Email</label>
  <input type="email" id="inputEmail" placeholder="Email" required="required" autofocus="autofocus" value="{{ old('email') }}" name="email" class="form-control"/>
@if ($errors->has('email'))<span class="help-block"><strong>{{ $errors->first('email') }}</strong></span>@endif
  <label for="inputPassword" class="sr-only">Пароль</label>
  <input type="password" id="inputPassword" placeholder="Пароль" required="required" name="password" class="form-control"/>
@if ($errors->has('password'))<span class="help-block"><strong>{{ $errors->first('password') }}</strong></span>@endif
  <div class="checkbox">
    <label>
      <input type="checkbox" value="remember-me"/>Запомнить
    </label>
  </div>{{ csrf_field() }}
  <button type="submit" class="btn btn-lg btn-primary btn-block">Вход</button>
</form>