Как оказалось не так уж просто, но все же возможно, причем вся логика - на серверной стороне, а значит метод кроссбраузерный!
Все что потребуется - контролировать пару флагов в сессии.
Суть в том, что если юзер авторизован - в сессии хранится его ID, а раз уж ID есть, то и пароль с логином спрашивать ни к чему. Однако есть и другой флаг, назовем его reauth, который показывает, что мы затребовали выход из системы.
При взведении этого флага сессия юзера очищается, а логин-пароль принудительно прячутся (т.е. метод getEnvLoginPasswd() просто говорит "а нету, пытай меня сволочь немецкая!"), это важно, иначе чуда не произойдет.
В итоге имеем такой класс:
class auth {
protected $suid = null; // current session user id
protected $suid_var = 'sess_uid';
protected $reauth_var = 'need_reauth';
public function __construct() {
session_start();
$this->suid = @$_SESSION[$this->suid_var];
}
public function check() {
if (!$this->isAuthorized()) {
return $this->requestAuth();
}
return $this->getSessionID();
}
public function isAuthorized() {
return ($this->getSessionID() or $this->isAccessGranted())
and empty($_SESSION[$this->reauth_var]);
}
protected function getSessionID() {
return $this->suid;
}
protected function isAccessGranted() {
if (!(list($login, $pass) = $this->getEnvLoginPasswd())) {
return false;
}
return $_SESSION[$this->suid_var] = $this->suid = $this->verifyCredentials($login, $pass);
}
protected function getEnvLoginPasswd() {
if (!empty($_SESSION[$this->reauth_var])) {
return false;
}
if (empty($_SERVER['PHP_AUTH_USER']) or empty($_SERVER['PHP_AUTH_PW'])) {
return false;
}
return array($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
}
protected function verifyCredentials($login, $pass) {
return $login == 'log' and $pass == 'pass';
}
public function logout() {
$_SESSION[$this->reauth_var] = true;
unset($_SESSION[$this->suid_var]);
$this->suid = null;
header('Location: /');
}
public function requestAuth() {
unset($_SESSION[$this->reauth_var]);
header('WWW-Authenticate: Basic realm="Hallou"');
header('HTTP/1.0 401 Unauthorized');
echo 'Требуется авторизация';
echo '<script>document.execCommand("ClearAuthenticationCache");</script>';
exit;
}
}
В методе verifyCredentials происходит проверка введенных данных. Имена методов вообще говорят сами за себя. Пользоваться классом просто:
Chrome и FF более охотно "забывают" данные для входа, поэтому с ними возни меньше.
$a = new auth;Метод должен был быть кроссбраузерным, но оказалось, что он не работает в опере и в ИЕ..
$a->check();
if ($_SERVER['QUERY_STRING'] == 'logout') {
$a->logout();
}
Chrome и FF более охотно "забывают" данные для входа, поэтому с ними возни меньше.
Чтобы сбросить кэш авторизации в ИЕ добавлена строка со скриптом в метод requestAuth();
Осталась только вредная опера.. может как нить руки дойдут допилить
P.S. В качестве бонуса данный метод позволяет ввести новую пару логин/пароль сразу, после разлогинивания, потому что перенаправляет нас с logout-экшена на главную.
Осталась только вредная опера.. может как нить руки дойдут допилить
P.S. В качестве бонуса данный метод позволяет ввести новую пару логин/пароль сразу, после разлогинивания, потому что перенаправляет нас с logout-экшена на главную.
Комментариев нет:
Отправить комментарий