Remember Me для Админ зоны в Joomla 3.2.3

Апрель 5, 2014

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

Сразу отмечу, что ни один плагин в Интернете не позволяет достигнуть аналогичного результата. Причем в моем случае почему-то даже стандартный KeepAlive не работал, сессия слетала и я переключался на форму логина каждые 15 минут (время жизни сессии по настройкам конфига). Сейчас даже если и сессия слетела, она восстановится. ОК, к делу.

Все правки в коде ищите по комментарию "// cay127".

Файл plugins/authentication/cookie/cookie.php

Правки ниже:

public function onUserAuthenticate($credentials, $options, &$response)
{
	// No remember me for admin
	if ($this->app->isAdmin())
	{
		// cay127
		// return false;
	}

В коде отменяется стандартное ограничение джумлы, хотя функционал "Запомнить пароль" работает для любого раздела сайта одинаково.

Это не все, но объяснять уже не буду, слишком долго.

public function onUserAfterLogout($options)
{
	// No remember me for admin
	if ($this->app->isAdmin())
	{
		// cay127
		// return false;
	}

Далее еще. Кусок кода большой, нужно развернуть:

public function onUserAfterLogin($options)
{
	// No remember me for admin
	if ($this->app->isAdmin())
	{
		// cay127
		$options[ 'remember' ] = 1;
		// return false;
	}

	if (isset($options['responseType']) && $options['responseType'] == 'Cookie')
	{
		// Logged in using a cookie
		$cookieName		= JUserHelper::getShortHashedUserAgent();

		// We need the old data to get the existing series
		$cookieValue	= $this->app->input->cookie->get($cookieName);
		$cookieArray	= explode('.', $cookieValue);
		// Filter series since we're going to use it in the query
		$filter			= new JFilterInput;
		$series			= $filter->clean($cookieArray[1], 'ALNUM');
	}
	elseif (!empty($options['remember']))
	{
		// Remember checkbox is set
		$cookieName		= JUserHelper::getShortHashedUserAgent();

		// Create an unique series which will be used over the lifespan of the cookie
		$unique = false;
		do
		{
			$series = JUserHelper::genRandomPassword(20);

			$query = $this->db->getQuery(true)
				->select($this->db->quoteName('series'))
				->from($this->db->quoteName('#__user_keys'))
				->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series));

			$results = $this->db->setQuery($query)->loadResult();

			if (is_null($results))
			{
				$unique = true;
			}
		}
		while ($unique === false);
	}
	else
	{
		return false;
	}

	// Get the parameter values
	$lifetime	= $this->params->get('cookie_lifetime', '60') * 24 * 60 * 60;
	$length		= $this->params->get('key_length', '16');

	// Generate new cookie
	$token		= JUserHelper::genRandomPassword($length);
	$cookieValue = $token . '.' . $series;

	// Overwrite existing cookie with new value
	$this->app->input->cookie->set(
		$cookieName, $cookieValue, time() + $lifetime, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain'), $this->app->isSSLConnection()
	);

	$query = $this->db->getQuery(true);

	// cay127
	$query = 'SELECT ' . $this->db->quoteName('id');
	$query .= ' FROM ' . $this->db->quoteName('#__user_keys');
	$query .= ' WHERE ' . $this->db->quoteName('series') . ' = ' . $this->db->quote($series);
	$query .= ' AND ' . $this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username);

	$results = $this->db->setQuery($query)->loadObjectList();
	if (count($results) !== 0) {
		$b_update = true;
	} else {
		$b_update = false;
	}

	$query = $this->db->getQuery(true);
	// cay127 #

	// cay127
	// if (!empty($options['remember']))
	if ($b_update == false AND !empty($options['remember']))
	{
		// Create new record
		$query
			->insert($this->db->quoteName('#__user_keys'))
			->set($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
			->set($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
			->set($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))
			->set($this->db->quoteName('time') . ' = ' . (time() + $lifetime));
	}
	else
	{
		// Update existing record with new token
		$query
			->update($this->db->quoteName('#__user_keys'))
			->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
			->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
			->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName));
	}

	$hashed_token	= JUserHelper::hashPassword($token);
	$query
		->set($this->db->quoteName('token') . ' = ' . $this->db->quote($hashed_token));

	$this->db->setQuery($query)->execute();

	return true;
}

Файл libraries/cms/application/administrator.php

И теперь самое, что может показаться странным, но джумла почему-то делает язык английским после окончания срока действия временной куки на час. Исправляем и это.

protected function initialiseApp($options = array())
{
	// cay127
	if ( $options[ 'language' ] == 'en-GB' ) {
		$options[ 'language' ] = '';
	}

В заключение

Все, можно наконец-то заняться кодингом, просмотром авто-обновлений статистики в режиме live и не переживать ни о чем.

Update 2014-04-06 

Что-то включил сегодня компьютер после сна и попал на форму логина:( Надеюсь не последнее добавление с языком повлияло таким образом, что меня стало выкидывать. Подумаю еще...

Update 2014-08-25 

Обновил джумлу, повторил все действия по своей инструкции и ничего не получилось. Видимо забыл еще один файл. Продолжаю.

plugins/system/remember/remember.php

1-е изменение:

public function onAfterInitialise()
{
	// No remember me for admin.
	if ($this->app->isAdmin())
	{
		// cay127
		// return;
	}

и 2-е:

public function onUserLogout($user, $options)
{
	// No remember me for admin
	if ($this->app->isAdmin())
	{
		// cay127
		// return true;

Короче всегда ищем "No remember me for admin" в консоли через grep и спасибо разработчикам за комментарии.

Tags: , , ,

Запись опубликована Суббота, Апрель 5, 2014 в 22:56 и находится в Joomla, Программирование . Вы можете следить за ответами к этой записи через RSS 2.0 ленту. Вы можете оставить комментарий, или обратиться к записи со своего сайта.

Оставить Комментарий

*