Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Решение задачи Авторизации и Заключения сеанса с HTTP Authentication: Basic, PHP, Joomla, Apache

Anna | 31.05.2014 | нет комментариев

Дословно вчера я решил приступить к разработке личного кабинете одного безымянного сайта. Передо мною встал вопрос по поводу внешнего вида формы авторизации, мне, искренне, не хотелось заниматься дизайном формы, делать всплывающие подсказки, да и в целом уделять большое внимание форме. Я сдуру ринулся искать готовые решения, увидел довольно невкусных форм. Думал подыскать какой-нибудь готовый компонент, готовое растяжение, но в большинстве своём они разочаровали меня. Странствуя по форумам, мне показалось увлекательным разыграть карту с HTTP Authentication: Basic. Я отправился читать мануал, раньше был неудовлетворительно осведомлён об данном методе. Дальше и начались задачи.

Деваться было некуда, пошастал по сети в поисках сайтов, что возьмутся генерировать формы, код, жанры. Напрасны оказались мои попытки облегчить себе задачу. Выход невелик, я приступил к разрешению задачи. Одно время я усердствовал сварганить решение с поддержкой .htaccess, обнаружил такое.

RewriteCond %{HTTP:Authorization} ^Basic.*
RewriteRule (.*) index.php?authorization=%{HTTP:Authorization} [QSA,L]

Увы, у меня появились задачи с Joomla, у неё и так всё хорошо в .htaccess, а здесь я еще со своим кодом. Уделив время на перебор разных комбинаций, я согласился с тем, что переписывать .htaccess я не буду. С начала код был дюже сырым, настоль сырым, что я только-только его скопипастил.

<?php
	if (!isset($_SERVER['PHP_AUTH_USER'])) {
		header('WWW-Authenticate: Basic realm="My Realm"');
		header('HTTP/1.0 401 Unauthorized');
		echo 'Текст, отправляемый в том случае, если пользователь нажал кнопку Cancel';
		exit;
	} else {
		echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
		echo "<p>Вы ввели пароль {$_SERVER['PHP_AUTH_PW']}.</p>";
	}
?>

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

<?php
$session = JFactory::getSession();
	if(!isset($_SERVER['PHP_AUTH_PW'])) {
		header('WWW-Authenticate: Basic realm="My Realm"');
		header('HTTP/1.0 401 Unauthorized');
	} else {
		//В случае с выявлением подходящего codeword - создаём сессию
		if($session->get('user') === null) {
			$db = JFactory::getDbo();
			$query = $db->getQuery(true);
			$query->select('*');
			$query->from('#__beda_users');
			$query->where('codeword = '.$query->quote($_SERVER['PHP_AUTH_PW']));
			if($res = $db->setQuery($query)->loadAssoc()) {
				$session->set('user', $res);
			} else {
				header('WWW-Authenticate: Basic realm="My Realm"');
				header('HTTP/1.0 401 Unauthorized');
			}
		} else {
			//Нам бы сюда
		}
	}
?>

Работает, значения меняются, сессия создаётся. Восхитительно, но в случае с кликом на отмену, значения$_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] плевать хотели, что ты отменил, позже обновления страницы, возвращаются на место. Я решил, что бороться следует с этим через unset. Я добавил строчку.

if($res = $db->setQuery($query)->loadAssoc()) {
	$session->set('user', $res);
} else {
	unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
	header('WWW-Authenticate: Basic realm="My Realm"');
	header('HTTP/1.0 401 Unauthorized');
}

Я усердствовал совладать с этими переменными, но всё глубже уходил в никуда. Устраивал и проверку существования сессии, но безуспешно. К тому же мне требовалось сделать заключение сессии, что с слов форумчан немного представляется допустимым. Докопался до истины применения адреса видаlogin:pass@locahost/. Восхитительно, переменные изменились $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']. Увы, но это не стало моим окончательным решением, от того что позже окончания времени сессии $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] продолжали исполнять. Как и позже принудительно присваивания $session->set(‘user’, null). Я вне себя от гнева, но знал, что не извиню себе, если дозволю отступиться. Я написал отдельное условие для проверки на логаут.

if($_SERVER['PHP_AUTH_USER']=='logout'){
	$session->set('user', null);
	header('Refresh: 0;URL=');
}
if(!isset($_SERVER['PHP_AUTH_PW'])) {
	header('WWW-Authenticate: Basic realm="My Realm"');
	header('HTTP/1.0 401 Unauthorized');
} else {
	//В случае с выявлением подходящего codeword - создаём сессию
	if($session->get('user') === null) {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true);
		$query->select('*');
		$query->from('#__beda_users');
		$query->where('codeword = '.$query->quote($_SERVER['PHP_AUTH_PW']));
		if($res = $db->setQuery($query)->loadAssoc()) {
			$session->set('user', $res);
		} else {
			unset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
			header('WWW-Authenticate: Basic realm="My Realm"');
			header('HTTP/1.0 401 Unauthorized');
		}
	} else {
		//Нам бы сюда
	}
}

Условие сработало, впрочем позже перезагрузки страницы, когда возникает окно с требованием ввести имя пользователя и пароль, оно их приняло, да позже обновление страницы, он предложил мне еще раз ввести пароль, нажму «Отмена», $_SERVER['PHP_AUTH_USER'] будет logout. Обновлю значения, он присвоит их. А нажму на отмену от вернёт бывшие значения. Напасть.

В конце концов окончательное решение выглядит так.

$session = JFactory::getSession();
function http_auth($session){
	$session->set('user', null);
	unset($_SERVER['PHP_AUTH_PW'],  $_SERVER['PHP_AUTH_USER']);
	header('WWW-Authenticate: Basic realm="Auth"');
	header('HTTP/1.0 401 Unauthorized');
}
if($_SERVER['PHP_AUTH_USER']=='logout'){
	$session->set('user', null);
	header('Refresh: 0;URL=');
}
if($session->get('user') === null){
	if(!isset($_SERVER['PHP_AUTH_PW'])){
		http_auth($session);
	} else {
		$pw = $_SERVER['PHP_AUTH_PW'];
		$db = JFactory::getDbo();
		$query = $db->getQuery(true);
		$query->select('*');
		$query->from('#__beda_users');
		$query->where('codeword = '.$query->quote($pw));
		if($res = $db->setQuery($query)->loadAssoc()){
			$session->set('user', $res);
		} else {
			http_auth($session);
		}
	}
} else {
	if(!isset($_SERVER['PHP_AUTH_PW'])){
		http_auth($session);
	}
}
На звание положительного, прекрасного, читабельного кода не претендую, это работает, а позже дозволено теснее и почистить.

Первые пример.
http://www.php.net/manual/ru/features.http-auth.php

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB