Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 23.10.2012 13:48:45

mephis

Authentication

Добрый день.
Начал работать с Laravel. Имеется таблица:
`user_id` int
`login_name` varchar
`pwd` varchar - шифруется в md5

использую:

Route::post('/login/process', function() {
	$user_data = array('username' => Input::get('login'), 'password' => md5(Input::get('password')));
	if (Auth::attempt($user_data)) 	{
	    return Redirect::to('home.index');
	}
	else {
		print_r($user_data);
	}
});

Авторизация не проходит. Как исправить?
Заранее спасибо.

#2 23.10.2012 14:21:01

Не в сети

#3 23.10.2012 14:40:39

mephis

Re: Authentication

Нашел решение проблемы.
Т.к. требования от заказчика жесткие и менять имена полей и алгоритм шифрования не разрешено, чуть подправил драйвер /laravel/auth/drivers/fluent.php
Исходная функция:

public function attempt($arguments = array())
	{
		$user = $this->get_user($arguments);

		// If the credentials match what is in the database we will just
		// log the user into the application and remember them if asked.
		$password = $arguments['password'];

		$password_field = Config::get('auth.password', 'password');

		if ( ! is_null($user) and Hash::check($password, $user->{$password_field}))
		{
			return $this->login($user->id, array_get($arguments, 'remember'));
		}

		return false;
	}

Переписанная функция:

public function attempt($arguments = array())
	{
		$user = $this->get_user($arguments);

		// If the credentials match what is in the database we will just
		// log the user into the application and remember them if asked.
		$password = $arguments['password'];

		$password_field = Config::get('auth.password', 'password');

		if ( ! is_null($user) and Hash::check($password, Hash::make($user->{$password_field}))) //Добавил генерацию хеша для значения поля 'pwd' в БД чтобы сравнивались правильные значения
		{
			return $this->login($user->user_id, array_get($arguments, 'remember')); //изменил стандартное поле id на user_id, что у меня в базе
		}

		return false;
	}

#4 23.10.2012 14:50:28

Cheshirrski
masterМастер
Откуда: Днепр
Сообщений: 116
Статей: 2

Re: Authentication

И это работает? Зачем вы хешируете название поля пароля пользователя?

Не в сети

#5 23.10.2012 14:56:20

mephis

Re: Authentication

Я хэширую не название пароля, а сам пароль $user->{$password_field}
Теперь появилась другая ошибка, после того как залогинился первый раз.

Message:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause'

SQL: SELECT * FROM `users` WHERE `id` = ? LIMIT 1

Bindings: array (
  0 => '1',
)
Location:

/var/www/laravel/laravel/database/connection.php on line 263

Подскажите, как прописать алиас для поля `iser_id`, по типу как в файле config/auth.php

#6 23.10.2012 15:12:50

Re: Authentication

Я бы лучше написал свой драйвер по примеру Eloquent/Fluent — слишком много менять нужно (алгоритм — не PHPHash::make(), а PHPmd5() и не PHP$user->id, а PHP$user->user_id). Класс получится строчек на 30 и ошибки возникать не будут, так как всё напишешь сам с нуля.

Не в сети

#7 23.10.2012 15:24:07

Cheshirrski
masterМастер
Откуда: Днепр
Сообщений: 116
Статей: 2

Re: Authentication

$password_field = Config::get('auth.password', 'password');
if ( ! is_null($user) and Hash::check($password, $user->{$password_field})) 
{
	return $this->login($user->user_id, array_get($arguments, 'remember')); 
}

$password_field = Config::get('auth.password', 'password'); //  эта строка означает "берем из конфига auth значение ключа password, в котором хранится название поля пароля пользователя".
Hash::check($password, $user->{$password_field})) // сравниваем принимаемый пароль $password со значением из базы данных(которое уже должно быть захешировано).

Изменено Cheshirrski (23.10.2012 15:25:13)

Не в сети

#8 23.10.2012 15:35:06

mephis

Re: Authentication

Hash::check($password, $user->{$password_field})) // сравниваем принимаемый пароль $password со значением из базы данных(которое уже должно быть захешировано).

оно не захешировано, поэтому я хэширую второй аргумент на ходу.
я выше писал, что пароли лежат в md5, а в attempt я передаю введенный пользователем пароль тоже в md5

#9 23.10.2012 15:53:32

Cheshirrski
masterМастер
Откуда: Днепр
Сообщений: 116
Статей: 2

Re: Authentication

Присоединяюсь к Proger_XP, быстрее написать свой драйвер.

Не в сети

#10 23.10.2012 16:11:41

Re: Authentication

  1. я выше писал, что пароли лежат в md5, а в attempt я передаю введенный пользователем пароль тоже в md5

А Fluent его ещё раз хэширует с помощью Hash::make(). Так что даже если ты исправишь ошибку с id, то авторизация всё равно не заработает.

Не в сети

#11 23.10.2012 16:11:53

mephis

Re: Authentication

заработало
написал свой драйвер md5.php
с таким методом:

public function attempt($arguments = array())
	{
		$user = $this->get_user($arguments);

		// If the credentials match what is in the database we will just
		// log the user into the application and remember them if asked.
		$password = $arguments['password'];

		$password_field = Config::get('auth.password', 'password');
		$id_field = Config::get('auth.id', 'id');

		if ( ! is_null($user) and md5($password)== $user->{$password_field})
		{
			return $this->login($user->user_id, array_get($arguments, 'remember'));
		}

		return false;
	}

зарегистрировал драйвер в файле /laravel/auth.php

protected static function factory($driver)
	{
		if (isset(static::$registrar[$driver]))
		{
			$resolver = static::$registrar[$driver];

			return $resolver();
		}

		switch ($driver)
		{
			case 'fluent':
				return new Auth\Drivers\Fluent(Config::get('auth.table'));

			case 'eloquent':
				return new Auth\Drivers\Eloquent(Config::get('auth.model'));
				
			case 'md5':
				return new Auth\Drivers\Md5(Config::get('auth.model'));

			default:
				throw new \Exception("Auth driver {$driver} is not supported.");
		}
	}

а чтобы убрать ошбику

Message:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause'

SQL: SELECT * FROM `users` WHERE `id` = ? LIMIT 1

Bindings: array (
  0 => '1',
)
Location:

/var/www/laravel/laravel/database/connection.php on line 263

в файле /laravel/database/query.php заменил все 'id' на 'user_id'

Могут в будущем быть ошибки?

#12 23.10.2012 16:31:46

Cheshirrski
masterМастер
Откуда: Днепр
Сообщений: 116
Статей: 2

Re: Authentication

Что-ж вы так прям "с мясом"? Очень даже могут. Наверное лучше создать свой query с нужными методами и указать его в драйвере через namespace.

Не в сети

#13 23.10.2012 16:42:48

mephis

Re: Authentication

Спасибо за советы.
Вышел из положения по-другому.
Проблема в том, что в таблица users используется еще несколькими ресурсами и её структуру нельзя трогать.
В итоге с заказчиком решили создать идентичную таблицу 'users_auth' (id,name,pass), в которую будем складывать пароли юзеров в bcrypt и работать с ними.

#14 23.10.2012 16:49:10

mephis

Re: Authentication

хотя я придумал вариант другой)
в класс query добавить переменную 'id_alias' и при инициализации читать конфиг, где будет строчка 'id' => 'user_id'.
а потом вместо статичной записи 'id' в query вставлять $this->id_alias

#15 25.10.2012 11:33:26

Re: Authentication

mephis пишет:

Добрый день.
Начал работать с Laravel. Имеется таблица:
`user_id` int
`login_name` varchar
`pwd` varchar - шифруется в md5

использую:

Route::post('/login/process', function() {
	$user_data = array('username' => Input::get('login'), 'password' => md5(Input::get('password')));
	if (Auth::attempt($user_data)) 	{
	    return Redirect::to('home.index');
	}
	else {
		print_r($user_data);
	}
});

Авторизация не проходит. Как исправить?
Заранее спасибо.

<?
class User extends Eloquent {
	public static $key = 'user_id';
}

Так не пробовали? Ключ id меняется на user_id,  больше ничего переписывать не нужно.
Класс Eloquent наследует Laravel\Database\Eloquent\Model.

get_class_methods('user')
Array
(
    [0] => __construct
    [1] => fill
    [2] => fill_raw
    [3] => accessible
    [4] => create
    [5] => update
    [6] => _find
    [7] => all
    [8] => _with
    [9] => has_one
    [10] => has_many
    [11] => belongs_to
    [12] => has_many_and_belongs_to
    [13] => push
    [14] => save
    [15] => delete
    [16] => timestamp
    [17] => sync
    [18] => changed
    [19] => dirty
    [20] => table
    [21] => get_dirty
    [22] => get_key
    [23] => set_key
    [24] => get_attribute
    [25] => set_attribute
    [26] => purge
    [27] => to_array
    [28] => __get
    [29] => __set
    [30] => __isset
    [31] => __unset
    [32] => __call
    [33] => __callStatic
)
get_class_vars('user')
Array
(
    [attributes] => Array
        (
        )

    [original] => Array
        (
        )

    [relationships] => Array
        (
        )

    [exists] => 
    [includes] => Array
        (
        )

    [key] => id
    [accessible] => 
    [hidden] => Array
        (
        )

    [timestamps] => 1
    [table] => 
    [connection] => 
    [sequence] => 
    [per_page] => 20
)
get_parent_class('user')
Laravel\Database\Eloquent\Model

Изменено oleg578 (25.10.2012 11:47:01)

Не в сети

#16 25.10.2012 15:30:56

Re: Authentication

  1. Класс Eloquent наследует Laravel\Database\Eloquent\Model.

Он скорее не наследует, а задан алиасом в application/config/application.php.

  1. В итоге с заказчиком решили создать идентичную таблицу ’users_auth’ (id,name,pass), в которую будем складывать пароли юзеров в bcrypt и работать с ними.

По-моему вы себе создаёте лишние проблемы. Чем не подходит вариант с собственным драйвером авторизации? Просто напишите его нормально, как Cheshirrski говорит, и будет удобно. Структуру БД менять тоже не придётся, лишних таблиц не нужно.

Не в сети

#17 25.10.2012 20:39:37

Re: Authentication

Свой предыдущий пост отменяю. Проверил, по крайней мере при авторизации этот метод не работает. Все-таки не даром в документации требуется наличие поля id  в базах...

Не в сети

#18 25.10.2012 21:14:02

Re: Authentication

  1. Все-таки не даром в документации требуется наличие поля id в базах…

Eloquent очень, очень неохотно работает с нестандартными полями, каковы в его понимании id, created_at и updated_at. Это, пожалуй, один из немногих больших косяков фреймворка — невозможность их переименовать без изменения кода ядра.

Не в сети

Подвал раздела