Http authorization with php

Secure PHP Resource with HTTP Authentication

HTTP authentication is the process of identifying and verifying users’ credentials to make sure they are permitted to access a web resource. To prevent unauthorized access to your PHP web application, you can protect sensitive files or endpoints using a username and a password. One common way of achieving this is by using basic HTTP authentication. In this security design pattern, every user making a request to a resource on your server must submit an Authorization header containing Base64 encoded credentials.

The Base64 algorithm used in this context is for encoding non-HTTP compatible characters submitted by users to accepted values, and you should not use it as an encryption alternative. You would force your users to pass their credentials via secure HTTPS in a production environment.

In this guide, you’ll create a password-protected PHP web resource on Ubuntu 20.04 server. This endpoint will return data for the available products in a JSON (JavaScript Object Notation) format when the user is authenticated. However, users submitting empty or invalid credentials will get an error.

Prerequisites

To follow along with this tutorial, make sure you have the following:

  • An Vultr Ubuntu 20.04 server.
  • A sudo user.
  • A LAMP Stack. You can also follow this tutorial on a Vultr One-Click LAMP server.
Читайте также:  Php send smtp yandex

Edit the Apache Configuration File

SSH to your server and start by editing the Apache configuration file. For HTTP authentication to work, Apache should allow the .htaccess file to override main settings.

Open the /etc/apache2/apache2.conf file.

$ sudo nano /etc/apache2/apache2.conf 
 Options Indexes FollowSymLinks AllowOverride None Require all granted 

Change the AllowOverride None directive to AllowOverride All as shown below.

 Options Indexes FollowSymLinks AllowOverride All Require all granted 

Enable Apache mod_rewrite Module

Enable Apache mod_rewrite module. This is a rule-based engine that rewrites incoming requests to the server. You’ll require this module to retrieve the values of the HTTP_AUTHORIZATION header in your PHP files.

Restart the Apache web server to refresh the settings that you’ve changed.

$ sudo systemctl restart apache2 

Create a Password Protected PHP File

The next step is creating a PHP web resource that displays data in JSON format for authenticated users. Open a new /var/www/html/sample.php file at the root directory of your web server.

$ sudo nano /var/www/html/sample.php 

Enter the information below into the file. Remember to replace EXAMPLE_PASSWORD with a strong value.

 'Authentication failed', 'message' => 'Invalid username or password', 'error_code' => '401', ]; echo json_encode($error , JSON_PRETTY_PRINT); > else < $products = []; $products[] = [ 'product_id' =>1, 'product_name' => 'WIRELESS KEYBOARD', 'retail_price' => '44.80', ]; $products[] = [ 'product_id' => 2, 'product_name' => 'LAPTOP BAG', 'retail_price' => '28.70', ]; $products[] = [ 'product_id' => 3, 'product_name' => 'MOUSE PAD', 'retail_price' => '5.67', ]; echo json_encode($products, JSON_PRETTY_PRINT); > 

The PHP code explained:

header('Content-Type: application/json'); 

The above line sends a header to a browser to format the data in the expected JSON format.

list($username, $password) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); 

The code snippet above decodes the Base64 encoded credentials submitted by users to two variables( $username and $password ).

. if ($username != 'john' || $password != 'EXAMPLE_PASSWORD') < header("HTTP/1.1 401 Unauthorized"); $error = [ 'title' =>'Authentication failed', 'message' => 'Invalid username or password', 'error_code' => '401', ]; echo json_encode($error , JSON_PRETTY_PRINT); > else < . >. 

In the above code, you’ve used the PHP logical if (. ) <. >else <. >statement to check if the user is submitting the required username and password combination. In this case, the correct user will be authenticated by the username john and EXAMPLE_PASSWORD as the password. In case those values don’t match, you’re throwing a JSON encoded error and a 401 header informing the user that authentication has failed.

. if ($username != 'john' && $password != 'EXAMPLE_PASSWORD') < . >else < $products = []; $products[] = [ 'product_id' =>1, 'product_name' => 'WIRELESS KEYBOARD', 'retail_price' => '44.80', ]; . echo json_encode($products, JSON_PRETTY_PRINT); . > 

In the code above, you’re creating an array of products and displaying them as a JSON encoded string for the authenticated users.

Modify the .htaccess File

Modify the .htaccess file for the HTTP authentication to work. Open the /var/www/html/.htaccess file.

$ sudo nano /var/www/html/.htaccess 

Add the line below into the file.

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 

Save and close the file. The rewrite rule above instructs Apache to copy the value of $_ENV[‘HTTP_AUTHORIZATION’] into the $_SERVER[‘HTTP_AUTHORIZATION’] variable. Remember, you are retrieving this value in the /var/www/html/sample.php file to get encoded users’ credentials.

Test HTTP Authentication

After you’ve modified the Apache settings, created a password-protected resource, and modified the .htaccess file, the next step is testing if everything is working as expected.

Use Linux curl command to request the resource as shown below. In the first attempt, don’t submit any credentials to check if you’ll get an error. The -i option instructs curl to include the HTTP response headers when displaying the output.

$ curl -i -H 'Accept:application/json' localhost/sample.php 

You should get an output similar to the one shown below confirming that you’re not authenticated.

HTTP/1.1 401 Unauthorized Date: Tue, 26 Jan 2021 09:27:19 GMT Server: Apache/2.4.41 (Ubuntu) Content-Length: 121 Content-Type: application/json

Try to access the resource with the correct credentials. The -u option converts the username and password to a Base64 encoded string under the hood when submitting the request to the server.

$ curl -u john:EXAMPLE_PASSWORD -i -H 'Accept:application/json' localhost/sample.php 

With the correct credentials, you should now get a list of products, as shown below.

HTTP/1.1 200 OK Date: Tue, 26 Jan 2021 09:30:50 GMT Server: Apache/2.4.41 (Ubuntu) Content-Length: 331 Content-Type: application/json [ < "product_id": 1, "product_name": "WIRELESS KEYBOARD", "retail_price": "44.80" >, < "product_id": 2, "product_name": "LAPTOP BAG", "retail_price": "28.70" >, < "product_id": 3, "product_name": "MOUSE PAD", "retail_price": "5.67" >] 

Repeat the same process with some incorrect credentials and see if you get an error.

$ curl -u john:WRONG_PASSWORD -i -H 'Accept:application/json' localhost/sample.php $ curl -u wrong_username:EXAMPLE_PASSWORD -i -H 'Accept:application/json' localhost/sample.php 

You should get an error in both cases.

HTTP/1.1 401 Unauthorized Date: Tue, 26 Jan 2021 09:27:19 GMT Server: Apache/2.4.41 (Ubuntu) Content-Length: 121 Content-Type: application/json

Conclusion

In this tutorial, you’ve secured a PHP web resource with HTTP Authentication on Ubuntu 20.04 server. To take your web server security even a step further, consider securing Apache with TLS/SSL Certificate.

Want to contribute?

You could earn up to $600 by adding new articles.

Источник

Аутентификация и авторизация на PHP

Изображение баннера

Чтобы создать проверку пользователя во всплывающем окне достаточно следующего кода:

Тем не менее, желательно добавить немного функционала:

Работать такой код будет довольно убого — если ввести пароль неверно не будет второй попытки. Придётся закрывать вкладку, идти в историю браузера и удалять там соответствующие данные.

В Firefox это Library → History → Clear Recent History → Active Logins

В Chrome это Passwords and other sing-in data (в Clear browsing data → Advanced)

В Safari это Clear History

Если пароль поменялся, пользователя со старым паролем не выкинет и т.д.

Примечание о совместимости

Пожалуйста, будьте осторожны при кодировании строк заголовка HTTP.

Чтобы гарантировать максимальную совместимость со всеми клиентами, ключевое слово «Basic» должно быть написано с прописной буквой «B», строка realm должна быть заключена в двойные (а не одинарные) кавычки, и ровно один пробел должен предшествовать коду 401 в строке заголовка HTTP/1.0 401. Параметры аутентификации должны быть разделены запятыми, как показано в приведенном выше примере дайджеста.

Очистить глобальные переменные

Очистить значения переменных $_SERVER[‘PHP_AUTH_USER’] и $_SERVER[‘PHP_AUTH_PW’] можно с помощью функции unset()

HTTP Digest Authentication

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

Аналогичный метод используется в рамках VoIP-протокола SIP для аутентификации сервером обращения со стороны клиента, т.е. оконечного терминала.

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

Технически, аутентификация по дайджесту представляет собой применение криптографической хеш-функции MD5 к секрету пользователя с использованием случайных значений для затруднения криптоанализа и предотвращения replay-атак. Работает на уровне протокола HTTP.

Это более продвинутый вариант HTTP Аутентификации.

Можно использовать следующие опции ( полный список в RFC )

domain — домен

Необязательный список URI (через пробел), которые защищены данным запросом на аутентификацию.

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

base64 или HEX строка которую генерирует сервер. Клиент должен вернуть opaque неизменённым.

nonce — Уникальное HEX число или base64 число, которое сервер генерирует вместе с каждый 401 запросом.

nonce должен быть в одинарных кавычках (не в двойных)

nonce-count — HEX число, содержащее количество запросов, которые клиент отправил с nonce в запросе.

От английского stale — устаревший.

Флаг, который показывает на то, что предыдущий запрос от клиента был отклонён из за того, что значение nonce было несвежим.

Сервер должен ставить флаг stale в TRUE (регистронечувствительный) если пароль и имя пользователя верные и только nonce устарел.

В этом случае клиент может попытаться отправить ещё один зашифрованный запрос не запрашивая у пользователя ввод пароля.

Если сервер отказал в соединении а stale поставлен в FALSE, либо любое значение кроме TRUE, либо вообще отсутствует, значит клиент должен запросить логин и пароль снова.

qop — Quality of Protection

Опция для HTTP Digest Authentication. Может принимать значения «auth» или «auth-int». Влияет на то как создается хэш.

Если поставить в «auth» будет использоваться только запрошенный URI. Если в «auth-int» то также будет использовано тело запроса.

cnonce — Уникальный id сгенерированный клиентом. Это число помогает клиенту и серверу подтвердить, что у них есть известный общий секрет. Необходимо когда сервер отправляет qop. Не должно посылаться если сервер не использовал qop директиву.

Обзор Digest Аутентификации

  1. Клиент шлёт GET на сервер.

WWW-Authenticate: Digest realm=»AndreiR»,
qop=»auth,auth-int»,
nonce=»abcdefg…»,
opaque=»abcd…»,

    Пользователь вводит свои учётные данные

HA1 = MD5 хэш из имени пользователя, пароля и строки realm.

HA2 = MD5 хэш из метода аутентификации и запрошенного URI

Response = MD5 хэш из HA1, HA2, nonce, nonce-count, cnonce и qop

GET /
Authorization: Digest username=»andrei», realm=»AndreiR», uri=»/»
qop=auth, nc=00000001,response=»12345abc…»
nonce=»abcdefg…»,
opaque=»abcd…»,

  1. Сервер проверяет пришедшие данные. Если всё верно возвращает HTTP 200 OK, если неверно HTTP 403 Forbidden

Некоторые опции необязательны, поэтому гарантировать определённый уровень безопасности нельзя.

HTTP Digest Аутентификация уязвима для атак посредника (MITM) так как сервер не может проверить идентичность клиента.

Невозможно использовать более сложные алгоритмы хэширования паролей, такие как bcrypt

Form Based Аутентификации

Про аутентификацию через HTML форму вы можете прочитать в статье «PHP Аутентификация через форму»

Источник

Оцените статью