Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Всем привет! Требуется помощь. Пытаюсь создать небольшую CRM для личного пользования. Laravel 5.3, ОС - Windows 8, OpenServer, MySQL.
Возникла проблема при регистрации пользователей. Стандартный класс для регистрации не подходит, т.к. добавлять пользователей должен только уже зарегистрированный администратор. Для добавления пользователей использую следующий код, используя стандартную модель User:
public function createUserStore(Request $request){
Validator::make($request->all(), array(
"userName" => 'required|max:255',
"userEmail" => 'required|email|max:255|unique:users,email',
"password" => 'required|min:6|confirmed',
"msLogin" => 'max:255|unique:users,ms_login',
"msPassword" => 'min:6|max:32',
)
);
$data = array(
'name' => $request->userName,
'email' => $request->userEmail,
'password' => bcrypt($request->userPassword),
'ms_login' => (!empty($request->msLogin)) ? $request->msLogin : NULL,
'ms_password' => (!empty($request->msPassword)) ? bcrypt($request->msPassword) : NULL,
);
User::create($data);
return redirect()->route('users');
}
В БД пользователь добавляется, но потом Laravel не пускает пользователей, созданных таким образом. Для аутентификации тоже использую стандартный класс.
То же самое происходит, когда я пытаю обновить данные пользователя:
public function updateUser(Request $request){
$user = User::find($request->userId);
Validator::make($request->all(), array(
"userName" => 'required|max:255',
"userEmail" => array(
'required|email|max:255',
Rule::unique('users')->ignore($user->id, 'email'),
),
"password" => 'required|min:6|confirmed',
"msLogin" => array(
'max:255',
Rule::unique('users')->ignore($user->id, 'ms_login'),
),
"msPassword" => 'min:6|max:32',
)
);
$user->name = $request->userName;
$user->email = $request->userEmail;
$user->password = bcrypt($request->userPassword);
$user->ms_login = $request->msLogin;
$user->ms_password = (!empty($request->msPassword)) ? bcrypt($request->msPassword) : NULL;
$user->save();
return redirect()->back();
}
При этом, пользователи, созданные стандартным классом, который идет из коробки, могут войти. А после изменения пароля моим методом, тоже не могут.
Помогите разобраться, пожалуйста.
Не в сети
Я считаю что вся проблема в том что вы используете напрямую bcrypt, laravel скорее всего использует "соль" при создании хеша пароля. Попробуйте использовать Hash::make($request->msPassword);
Не в сети
К сожалению, проблема была не в этом. Она продолжается. И ругается, кажется на логин именно. Стандартный метод аутентификации помечает поле логин красным и пишет: These credentials do not match our records.
Не в сети
Когда ошибка вылетает, поле email и пароль для входа используется? Если используется не емэйл (а поле ms_login, например), тогда необходимо изменить поле для логина переобпределив метод username в LoginController:
public function username()
{
return 'ms_login';
}
Если нестандартные поля используются для логина и пароля, тогда нужно использовать метод attempt:
if (auth()->attempt(['ms_login' => $request->msLogin, 'ms_password' => $request->msPassword]))
Изменено AlexeyMezenin (03.08.2017 16:27:42)
Не в сети
Да, используются именно те значения, которые положил в email и password:
$user->email = $request->userEmail;
$user->password = Hash::make($request->userPassword);
И в БД добавляются они тоже правильно - email в email, password в password. При этом стандартный метод регистрации добавляет в БД так же (кажется). Но зарегистрированные пользователи коробочным методом удачно проходят аутентификацию и авторизацию, а созданные моим кривым - нет.
Может быть, нужно использовать ещё какой-то фасад дополнительно? А не просто добавлять строку в таблицу, как фактически делаю я?
Не в сети
Может быть, нужно использовать ещё какой-то фасад дополнительно? А не просто добавлять строку в таблицу, как фактически делаю я?
Нет.
Если ты вручную продублируешь в БД какого нибудь пользователя, изменив его уникальные поля (типа логина и почты, оставив хэш пароля) - ты сможешь авторизоваться.
Странная проблема.
Может с кодировкой что?
Изменено covobo (03.08.2017 18:20:57)
Не в сети
Вот именно. При этом, даже изменив у пользователя, к примеру, не логин или пароль, а имя пользователя. Оно успешно меняется. Дальше - разлогиниваемся, пытаемся снова зайти под этим пользователем, и всё - не пускает.
Не в сети
Может с кодировкой что?
Кодировка везде UTF-8
Не в сети
Не в сети
Если ты вручную продублируешь в БД какого нибудь пользователя, изменив его уникальные поля (типа логина и почты, оставив хэш пароля) - ты сможешь авторизоваться.Странная проблема.
Действительно, вручную продублировал строку в БД, заменил уникальные поля, авторизовался без проблем.
Не в сети
Попробуйте при логауте session()->flush(), пароль создавать через bcrypt. Я обычно добавляю в модель User
PHP public function setPasswordAttribute($value) { $this->attributes['password'] = bcrypt($value); }
Не понял. Вообще, т.к. я использую стандартный метод аутентификации, то при логауте итак используется session()->flush()
/**
* Log the user out of the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->flush();
$request->session()->regenerate();
return redirect('/');
}
А после добавления в модель User кода:
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}
где это будет использоваться? Прошу прощения, если вопрос тупой)
Не в сети
где это будет использоваться? Прошу прощения, если вопрос тупой)
Ты заранее используешь bcrypt, тебе не обязательно это использовать.
Это мутатор https://laravel.com/docs/5.4/eloquent-mutators
Не в сети
Используй bcrypt() как использовал до этого. Проблема не здесь, т.к. Laravel сам использует этот хелпер.
Покажи нам миграцию и модель. Может быть у тебя еще что-то висит в событиях Eloquent?
Не в сети
Не в сети
Если при авторизации используется кастом поле для пароля, нужно это указать в User
PHP public function getAuthPassword() { return $this->ms_password; }
Скажите, а зачем у вас два поля для пароля? Какие поля вы отправляете при авторизации?
Я не использую кастомных полей ни для логина, ни для пароля. MS_login и ms_password - это логин и пароль для сервиса Мой склад, которые будут использоваться для взаимодействия с этим сервисом по API.
Использую стандартные поля email и password.
Не в сети
Стандартная миграция для создания таблицы Users:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
Я дополнил миграцией:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddColumnsToUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('ms_login')->nullable();
$table->string('ms_password')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['ms_login', 'ms_password']);
});
}
}
В модели только добавил в $fillable и $hidden свои значения:
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password', 'ms_login', 'ms_password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token', 'ms_password',
];
}
Не в сети
А до Eloquent я ещё не добрался)
Вообще, полагаю, что проблема почему-то с моими логинами, у тех пользователей, которые созданы моим способом.
Потому что в трейте AuthenticatesUsers в методе Login() именно созданные моим способом логины не попадают в этот if:
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
Вот сижу, ковыряюсь, как это всё происходит. И почему созданные стандартным контроллером RegisterController пользователи попадают в этот if.
Есть догадки?
Не в сети
Нашел ещё 1 странное поведение. Убрал bcrypt при создании пользователя. То есть кладу пароли не зашифрованными:
public function createUserStore(Request $request){
Validator::make($request->all(), array(
"userName" => 'required|max:255',
"userEmail" => 'required|email|max:255|unique:users,email',
"password" => 'required|min:6|confirmed',
"msLogin" => 'max:255|unique:users,ms_login',
"msPassword" => 'min:6|max:32',
)
);
$data = array(
'name' => $request->userName,
'email' => $request->userEmail,
'password' => $request->userPassword,
'ms_login' => (!empty($request->msLogin)) ? $request->msLogin : NULL,
'ms_password' => (!empty($request->msPassword)) ? $request->msPassword : NULL,
);
User::create($data);
return redirect()->route('users');
}
Валидацию проходит, в массив $data все данные добавляются, но при User::create вылазит ошибка, мол поле password пустое:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'password' cannot be null (SQL: insert into `users` (`name`, `email`, `password`, `ms_login`, `ms_password`, `updated_at`, `created_at`) values (Кент, kent@kent.com, , kent@company, 987654321, 2017-08-04 18:10:33, 2017-08-04 18:10:33))
Отсюда и ошибка при авторизации, видимо. bcrypt хешировал пустую строку и в БД всё выглядело как надо, а при попытке войти - борода.
Теперь вопрос - почему в массив $data password добавляется. А уже при создании пользователя куда-то девается???
Не в сети
Так что из формы приходит - password или userPassword? Валидатор проверяет password, а создается из $request->userPassword.
Изменено Sergant210 (04.08.2017 21:48:05)
Не в сети
Так что из формы приходит - password или userPassword? Валидатор проверяет password, а создается из $request->userPassword
Точно блин! 2 дня голову ломал!!! Я пару раз туда-обратно менял password на userPassword при тестировании валидатора, а тут ошибки и не заметил! Спасибо большое!!!
Не в сети
Страницы 1