Авторизация через .htaccess

У сервера apache есть возможность сделать базовую авторизацию. Чтобы закрыть директорию, в неё нужно поместить два файла – .htaccess и .htpasswd.

AuthType Basic
AuthName "Authorization"
AuthUserFile /путь_до_директории/.htpasswd
Require valid-user
htaccess

AuthName "Authorization" – сообщение в окне ввода логина и пароля, кириллица не поддерживается, в Google Chrome вообще не выводится.

AuthUserFile /путь_до_директории/.htpasswd – путь до файла с паролями.

Чтобы узнать полный путь к директории достачно поместить в неё PHP файл и запустить его в браузере.

<?php
echo dirname(__FILE__);
PHP

Авторизацией можно закрыть только определенные файлы, например архивы ZIP.

<Files arhive.zip>
AuthType Basic
AuthName "Authorization"
AuthUserFile /путь_до_директории/.htpasswd
Require valid-user
</Files>
htaccess

На некоторых хостингах авторизация на статические файлы (изображения, шрифты и т.д.) может не работать т.к. они отдаются через Nginx.

Стоит проверить прямой доступ к самим файлам .htaccess и .htpasswd из браузера, если да, то закрыть его:

<FilesMatch ".(htaccess|htpasswd)$">
Order Allow,Deny
Deny from all
</FilesMatch>
htaccess

В файле хранится пары логина и хеша пароля, например:

admin:$apr1$TCrF2kqA$TSMYziwt.qCkrct9yx4vv1

Логин может содержать латинские буквы, цифры, - и _, регистрозависимый.

Хеш можно сгенерировать в PHP, возможны следующие алгоритмы:

Bcrypt

В настоящее время считается очень безопасным, работает начиная с версии 2.4, формат:

$2y$ или $2a$ + результат алгоритма crypt_blowfish.

function bcrypt($password)
{
	$rounds = 12;
	$salt = sprintf('$2a$%02d$', $rounds) . substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 22);
	return crypt($password, $salt);
}

echo bcrypt('123456'); // $2a$12$dMHIiiPfeSMxqj3/Wt1.z.Mo7NPza1x/WANl7hDXZJzxxKKorz5um
PHP

MD5 (APR)

Специфический алгоритм Apache (1000 итераций MD5 случайной соли и пароля), работает во всех версиях.

$apr1$ + результат алгоритма.

function crypt_apr1_md5($password)
{
	$salt = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789'), 0, 8);
	$len = strlen($password);
	$text = $password . '$apr1$' . $salt;
	$bin = pack('H32', md5($password . $salt . $password));
	for($i = $len; $i > 0; $i -= 16) {
		$text .= substr($bin, 0, min(16, $i));
	}
	for($i = $len; $i > 0; $i >>= 1) {
		$text .= ($i & 1) ? chr(0) : $password{0};
	}
	$bin = pack('H32', md5($text));
	for($i = 0; $i < 1000; $i++) {
		$new = ($i & 1) ? $password : $bin;
		if ($i % 3) {
			$new .= $salt;
		}
		if ($i % 7) {
			$new .= $password;
		}
		$new .= ($i & 1) ? $bin : $password;
		$bin = pack('H32', md5($new));
	}
   
	$tmp = '';
	for ($i = 0; $i < 5; $i++) {
		$k = $i + 6;
		$j = $i + 12;
		if ($j == 16) $j = 5;
		$tmp = $bin[$i] . $bin[$k] . $bin[$j] . $tmp;
	}
	$tmp = chr(0) . chr(0) . $bin[11] . $tmp;
	$tmp = strtr(
		strrev(substr(base64_encode($tmp), 2)),
		'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
		'./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
	);
 
	return '$apr1$' . $salt . '$' . $tmp;
}

echo crypt_apr1_md5('123456'); // $apr1$h9j4azoy$unmKNqjZlRfZv5xRetm9p1
PHP

Crypt

Работает только на Unix хостингах и до версии Apache 2.2.17. Ограничивает длину пароля до 8 символов. Считается небезопасным.

function crypt3($password)
{
	return crypt($password, substr($password, 0, 2));
}

echo crypt3('123456'); // 12tir.zIbWQ3c
PHP

SHA-1

Этот алгоритм небезопасен по современным стандартам, работает во всех версиях.

{SHA} + результат SHA-1 (бинарная строка из 20-ти символов) закодированный в Base64.

function hash_sha1($password)
{
	return '{SHA}' . base64_encode(sha1($password, true));
}

echo hash_sha1('123456'); // {SHA}fEqNCco3Yq9h5ZUglD3CZJT4lBs=
PHP

Реквизиты доступа к закрытой директории можно передать в URL:

https://логин:пароль@example.com/path

Если такие URL использовать в src изображений, скриптов и стилей, то работать они не будут, вызвав ошибку:

Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are blocked.

Завершение сеанса происходит по закрытию браузера, но не вкладки. Другого варианта не предусмотрено.

В PHP можно отследить авторизированного пользователя по переменным массива $_SERVER.

echo $_SERVER['PHP_AUTH_USER']; // admin
echo $_SERVER['PHP_AUTH_PW'];   // 123456
PHP

Если их нет, значит пользователь не авторизирован. Вывести диалог входа из PHP:

header('WWW-Authenticate: Basic realm="Authorization"');
header('HTTP/1.0 401 Unauthorized');
PHP
15.11.2019, обновлено 04.12.2021
18277
Предыдущая запись Сортировка в MySQL
Следующая запись Выполнение заданий по Cron

Комментарии

, чтобы добавить комментарий.

Другие публикации

Шифрование полей в MySQL
В MySQL есть несколько встроенных функций шифрования. Рассмотрим основные на примерах c использованием PHP PDO.
11198
+1
Массив $_SERVER
Описание значений глобального массива $_SERVER с примерами.
22361
0
Работа с FTP в PHP
Протокол FTP – предназначен для передачи файлов на удаленный хост. В PHP функции для работы с FTP как правило всегда доступны и не требуется установка дополнительного расширения.
6456
+1
Загрузка файлов на сервер PHP
В статье приведен пример формы и php-скрипта для безопасной загрузки файлов на сервер, возможные ошибки и рекомендации при работе с данной темой.
45082
+17
Примеры использования cURL в PHP
cURL PHP – это библиотека предназначенная для получения и передачи данных через такие протоколы, как HTTP, FTP, HTTPS....
115598
+16
Запрет выполнения PHP скриптов в директории
Если нужно запретить выполнение скриптов php в директории, например в uploads, нужно поместить туда файл .htaccess со...
12238
+9