Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
версия Laravel:
php artisan -V
Laravel Framework version 5.1.1 (LTS)
Читаю доки-уроки по аутентификации в 5-м и натыкаюсь на несоответствия.
Ввиду малого опыта, процесс обучения затягивается.
Итак. Создал миграцию с таблицей users:
public function up()
{
Schema::create('users', function(Blueprint $table) {
// ID пользователя
$table->increments('id');
// E-Mail (уникальный)
$table->string('email')->unique();
// Пароль. Для используемой в Laravel хэш-функции требуется не меньше 60 символов
$table->string('password', 60);
// Никнейм
$table->string('username')->unique();
// Админ?
$table->boolean('isAdmin');
// Активирован?
$table->boolean('isActive')->index();
// Код активации аккаунта
$table->string('activationCode');
// Токен для возможности запоминания пользователя
$table->rememberToken(); // remember_token
// created_at, updated_at
$table->timestamps();
});
}
В БД таблица появилась.
Дальше создаю по уроку:
https://laracasts.com/series/laravel-5- … pisodes/15 - создаю путь:
Route::controller(['auth' => 'Auth\AuthController']);
php artisan route:list - вываливает ошибку:
Missing argument 2 for Illuminate\Routing\Router::controller(), called in F
:\OpenServer\domains\project\vendor\laravel\framework\src\Illuminate\Suppor
t\Facades\Facade.php on line 210 and defined
Смотрю доки: упоминается шаблон resources/views/auth - у себя не нахожу каталог auth
Потом в уроке ссылаются на trait AuthenticatesAndRegistersUsers
у меня он не такой как в уроке:
namespace Illuminate\Foundation\Auth;
trait AuthenticatesAndRegistersUsers
{
use AuthenticatesUsers, RegistersUsers {
AuthenticatesUsers::redirectPath insteadof RegistersUsers;
}
}
Собственно как создать простую авторизацию в 5.1.1?
Не в сети
php artisan|grep table
потом генеришь дефолтные миграции.
затем правишь их.
своих оверрайдов не надо писать, а то напонатыкаешься на несоответствий.
корректируй существующие.
+
5.1 отличается от 5.0, не серьёзно, но уже от многих старых рнр-фишек отказались в пользу новых.
Не в сети
Пришлось ковырять инглиш
Route::controller(['auth' => 'Auth\AuthController']); - это похоже в 5.1 не работает.
рекомендуют так:
Route::get('auth/login', 'Auth\AuthController@getLogin');
Route::post('auth/login', 'Auth\AuthController@postLogin');
Route::get('auth/logout', 'Auth\AuthController@getLogout');
// Registration routes...
Route::get('auth/register', 'Auth\AuthController@getRegister');
Route::post('auth/register', 'Auth\AuthController@postRegister');
ну и дальше тоже есть отличия от 5.0.
http://laravel.com/docs/5.1/authentication
Не в сети
Хотелось бы немного изменить дефолтную регистрацию. В частности, нужно отсылать пользователю email с предложением подтвердить регистрацию, после подтверждения пользователь может входить. Стандартный механизм регистрации описан в трейте \project\vendor\laravel\framework\src\Illuminate\Foundation\Auth\RegistersUsers.php
согласно логике, пользователь при отправке формы регистрации проходит валидацию контроллера \project\app\Http\Controllers\Auth\AuthController.php, и если все ок, система сразу его логинит.
Я могу переделать метод postRegister RegistersUsers.php - но меня смущает, что придется ковырять файл движка.
Или отказаться от стандартного механизма и написать свой с нуля используя Ручную аутентификацию и метод attempt? Как обычно принято делать в таких случаях?
Не в сети
Route::controller(['auth' => 'Auth\AuthController']);
если ты передаёшь массив, должно быть ::controllers
Не в сети
если ты в контроллере объявляешь метод, который совпадает с именем из трейта — метод контроллера перекроет метод из трейта. т.е. его можно просто скопипастить оттуда и переделать как считаешь нужным.
/**
* Handle a registration request for the application.
*
* @param Request $request
* @param MailQueue $mailer
*
* @return array|Response
*/
public function postRegister(Request $request, MailQueue $mailer)
{
$validator = $this->registrar->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException($request, $validator);
}
/** @var User $user */
$user = $this->registrar->create($request->all());
$url = action('Auth\AuthController@getConfirm', [ $user->confirmation_code ]);
$mailer->queue('emails.confirm', compact('url', 'user'), function ($message) use ($user, $url)
{
$message->to($user->email)->subject('Подтверждение регистрации');
});
return ...;
}
/**
* Подтверждение регистрации пользователем
*
* @param Request $request
* @param User $user
* @param string|null $token
*
* @return Response
*/
public function getConfirm(Request $request, User $user, $token = null)
{
if (is_null($token)) {
throw new NotFoundHttpException;
}
/** @var User $user */
$user = $user->whereConfirmationCode($token)->first();
if (!$user) {
return view('auth.noconfirm')->withMessage('Пользователь с таким кодом подтверждения не найден. Если это ошибка, свяжитесь с нами.');
}
if ($user->confirmed) {
return view('auth.noconfirm')->withMessage('Ваш пользовательский аккаунт уже активирован. Нажмите "Войти" и введите свой логин и пароль, или воспользуйтесь восстановлением пароля.');
}
$user->confirmed = true;
$user->save();
return ...;
}
Изменено constb (01.07.2015 09:05:53)
Не в сети
Не в сети
Спасибо. Попробую внедрить.
Не в сети
Сделал заготовку с стандартной авторизацией (вход, выход, восстановление пароля)
https://github.com/zloadmin/laravel51_with_auth
а зачем весь проект форкнул?
Не в сети
а зачем весь проект форкнул?
Почему нет?
Попробую прокомментировать Ваш код.
public function postRegister(Request $request, MailQueue $mailer)
{
$validator = $this->registrar->validator($request->all()); //"registrar->" - для 5.1 это убрать
// проверяем правильность введенных данных.
if ($validator->fails()) {
$this->throwValidationException($request, $validator);
}
/** @var User $user */
//записываем в базу нового пользователя
$user = $this->registrar->create($request->all()); //"registrar->" - для 5.1 это убрать
//генерируем URL подтверждения
$url = action('Auth\AuthController@getConfirm', [ $user->confirmation_code ]); //я понимаю генерация кода происходит в функции create(). Очень хотелось бы увидеть код !!!
//ставим письмо в очередь на отправку
$mailer->queue('emails.confirm', compact('url', 'user'), function ($message) use ($user, $url)
{
$message->to($user->email)->subject('Подтверждение регистрации');
});
//возврат после регистрации придумайте сами
return ...;
}
/**
* Подтверждение регистрации пользователем
*
* @param Request $request
* @param User $user
* @param string|null $token
*
* @return Response
*/
public function getConfirm(Request $request, User $user, $token = null)
{ //эта проверка для меня не понятна, пробел знаний:
if (is_null($token)) {
throw new NotFoundHttpException;
}
/** @var User $user */
//находим в БД пользователя
$user = $user->whereConfirmationCode($token)->first(); //буду признателен за комментарий по поводу связи кода подтверждения и токена. Имею пробел знаний.
//если не найден:
if (!$user) {
return view('auth.noconfirm')->withMessage('Пользователь с таким кодом подтверждения не найден. Если это ошибка, свяжитесь с нами.');
}
//если уже подтвержден
if ($user->confirmed) {
return view('auth.noconfirm')->withMessage('Ваш пользовательский аккаунт уже активирован. Нажмите "Войти" и введите свой логин и пароль, или воспользуйтесь восстановлением пароля.');
}
//поднимаем флаг пользователь подтвержден
$user->confirmed = true;
//записываем в БД
$user->save();
// тут пишем возврат на свой вкус
return ...;
//Ламерский вопрос. Почему не используется конструкция if - else? return обрывает выполнения кода?
}
Не в сети
Чей? Мой? Ну как бы там кроме view всё стандартное. Тоесть там Laravelий контролер и модель. А вьюхи я делал по документации.
$validator = $this->registrar->validator($request->all()); //"registrar->" - для 5.1 это убрать
возможно. копипастил из проекта на 5.0. там используется App\Services\Registrar, который реализует Illuminate\Contracts\Auth\Registrar и даёт методы validator и create.
$url = action('Auth\AuthController@getConfirm', [ $user->confirmation_code ]); //я понимаю генерация кода происходит в функции create(). Очень хотелось бы увидеть код !!!
код генерирует create в Registrar, он заполняет данные пользователя из полей формы, а код - это просто рандомная строка:
public function create(array $data)
{
$user = new User;
$user->fill([
'login' => $data['login'],
'name' => $data['first_name'] . ' ' . $data['last_name'],
'email' => $data['email'],
'phone' => $data['phone'],
'password' => bcrypt($data['password']),
]);
$user->confirmed = false;
$user->confirmation_code = str_random(128);
$user->save();
return $user;
}
{ //эта проверка для меня не понятна, пробел знаний:
if (is_null($token)) {
throw new NotFoundHttpException;
}
тут дело в том, что AuthController в маршутах подключен хелпером Route::controllers. При таком способе его параметры передаются в порядке очерёдности. Если сделать php artisan route:list, мы увидим для getConfirm:
/auth/confirm/{one?}/{two?}/{three?}/{four?}/{five?}
знак вопроса означает что параметр опционален, поэтому для токена задано значение по умолчанию = null. то есть если пользователь откроет /auth/confirm без токена, вместо крэша он получит осмысленное сообщение об ошибке. в данном случае - ошибка 404, потому что такой страницы, без токена, вроде как не существует.
$user = $user->whereConfirmationCode($token)->first(); //буду признателен за комментарий по поводу связи кода подтверждения и токена. Имею пробел знаний.
особенности нейминга. $token - это и есть код подтверждения. в модели он хранится в поле confirmation_code. whereConfirmationCode($token) - это в Eloquent синоним для where('confirmation_code', '=', $token)
//Ламерский вопрос. Почему не используется конструкция if - else? return обрывает выполнения кода?
да. на ларакастах есть отдельный каст из серии "simple rules for simpler code" с названием "don't use else". логика такая, что зачастую мы возвращаем значения в условиях и else только увеличивает уровень вложенности кода, что снижает его читаемость. также else - признак того, что функция становится слишком сложной и для лучшей читаемости кода, какую-то его часть, включающую этот if лучше вынести в отдельный метод и дать ему осмысленное название, описывающее что в этом месте кода делается.
это не значит, что else также плох как goto, но часто бывает, что он является признаком того, что код пора рефакторить. один из code smells - это слишком большой уровень вложенности.
в коде ларавеля очень много похожих мест:
if ($condition = true)
return $this->error();
$this->doSomething();
$this->doSomethingElse();
return $this->generateResult();
это кажется чушью, но на самом деле, когда я начал следовать этой рекомендации, я заметил, что мой код стал лучше. опять же повторю, это не абсолютное правило, но зачастую да - else не нужен.
Изменено constb (03.07.2015 11:40:24)
Не в сети
Страницы 1