# Как работает авторизация в WEB-приложениях и какая она бывает

## Cookie: к**ак сервер «узнает» пользователя между запросами**

HTTP - это протокол без сохранения состояния. То есть каждый следующий запрос ничего не знает про предыдущий. Например, первым запросом я могу авторизоваться на сайте как "Вася", вторым я хочу отправить сообщение Мише. Серверу надо как-то понять, что именно Вася отправляет сообщение. Для этого и используются Cookie.&#x20;

Когда вы входите на сайт, сервер не хранит ваши данные в открытом виде постоянно. Вместо этого он использует **сессии** и **cookie**.

**Cookie** — это небольшие фрагменты данных, которые сервер отправляет браузеру, и которые браузер сохраняет и отправляет обратно с каждым запросом к этому серверу. Они содержат уникальный **идентификатор сессии** (например, `session_id=abc123`).

**Как это работает:**

1. Пользователь вводит логин и пароль → сервер проверяет их.
2. Если данные верны, сервер создает **сессию** (запись в базе данных) и отправляет браузеру cookie с `session_id`. Через заголовок `Set-Cookie`.&#x20;
3. При каждом новом запросе браузер автоматически отправляет cookie обратно → сервер проверяет `session_id` и «узнает» пользователя.

### **Безопасность cookies**

Чтобы злоумышленники не могли украсть сессию, cookie защищают специальными флагами:

* **Secure:** Передаются только по HTTPS (шифрованному соединению).
* **HttpOnly:** Недоступны через JavaScript → защита от XSS-атак.
* **SameSite:** Отправляются только в рамках одного сайта → защита от CSRF.

{% hint style="info" %}
Кража Cookie  - обычно результат Client Side Attacks. То есть когда атаке подвергается не веб-сервер, а браузер пользователя.&#x20;
{% endhint %}

## **Пароли: как их хранят и почему передают в открытом виде**

Когда вы авторизутеесь на сайте через форму, то если посмотреть запрос, который отправляется на сервер, то можно обнаружить, что пароль в теле запроса передается в открытом виде. На самом деле это нормально. Когда вы вводите пароль в браузере, он передается в **зашифрованном виде** благодаря **SSL/TLS** (протокол HTTPS). А хешируется он уже на стороне сервера.&#x20;

<details>

<summary>SSL/TLS</summary>

**Как это работает:**

1. Браузер и сервер устанавливают защищенное соединение.
2. Все данные (включая пароль) шифруются → даже если их перехватят, расшифровать будет невозможно.

Не стоит вводить пароль на сайтах, которые не используют TLS -  HTTP (без «S»), пароль передается открыто. \
Либо на сайтах с недоверенным сертификатом - это может означать, что прервал цепочку доверенных сетрификатов и встал где-то "посередине", чтобы перехватывать и читать запросы в открытом виде.&#x20;

Продробнее: [ssl-tls-i-pki](https://vasilisa-l.gitbook.io/blue-team-cookbook/ssl-tls-i-pki "mention")

</details>

На стороне клиента никак не проверить **хеширование**. Но хеширование считается хорошей практикой: даже если злоумышленник взломает базу данных, он не должен получить доступ к паролям.&#x20;

**Хеш + Соль = Защита**

* **Хэш** — результат работы математической функции, которая превращает пароль в необратимую строку (например, `sha256("qwerty") → "65e84...c9d4"`).
* **Соль (salt)** — случайная строка, добавляемая к паролю перед хэшированием. Это защищает от атак по готовым таблицам хэшей (rainbow tables).

| Логин | Соль    | Хэш пароля              |
| ----- | ------- | ----------------------- |
| Alice | `x!p2L` | `sha256("qwertyx!p2L")` |
| Bob   | `9$fG`  | `sha256("1234569$fG")`  |

Продробнее: [kriptografiya-dlya-analitika-soc](https://vasilisa-l.gitbook.io/blue-team-cookbook/other/kriptografiya-dlya-analitika-soc "mention")

***

## **Авторизация через токены: альтернатива cookies**

Современные приложения часто используют **токены** вместо сессий. Самый популярный формат — **JWT** (JSON Web Token). Токены не требуют хранения сессий на сервере (stateless). Легко масштабируется для микросервисов.&#x20;

JWT - это строка вида:

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```

Она состоит из трех частей:

1. **Header** — алгоритм шифрования.
2. **Payload** — данные пользователя (логин, права, срок действия).
3. **Signature** — подпись, которая проверяет целостность токена.

#### **Как это работает?**

1. Пользователь вводит логин и пароль → сервер проверяет их и генерирует JWT.
2. Токен сохраняется на клиенте (например, в localStorage браузера).
3. При каждом запросе токен передается в заголовке:

   ```http
   Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
   ```
4. Сервер проверяет подпись токена → предоставляет доступ.

### **Заголовок Authorization**

Заголовок `Authorization` используется для передачи данных аутентификации (например, токенов) в HTTP-запросах.

```
Authorization: <тип> <данные>
```

**Типы авторизации**

* **Basic:**\
  Логин и пароль передаются в base64-кодировке. Считай, в открытом виде - не рекомендуется для production.

  ```
  Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
  ```
* **Digest:**\
  Использует хэширование для передачи данных аутентификации. Более безопасный, чем Basic, так как пароль не передается в открытом виде.

  ```
  Authorization: Digest username="user", realm="example", nonce="abc123", uri="/", response="hash"
  ```
* **Bearer:**\
  Используется для передачи токенов (например, JWT).

  ```
  Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
  ```

  * Токены могут быть ограничены по времени действия и правам.
  * Не требуют хранения состояния на сервере (stateless).

## **OAuth 2.0: авторизация для сторонних приложений**

Когда вы входите на сайт через Google, Facebook или GitHub, используется протокол **OAuth 2.0**.

OAuth 2.0 — это протокол для авторизации, который позволяет приложениям получать ограниченный доступ к ресурсам пользователя без передачи логина и пароля. Часто используется для предоставление доступа к API сторонним приложениям.

#### **Как работает OAuth 2.0**

1. Вы нажимаете «Войти через Google» → Spotify перенаправляет вас на сервер Google.
2. **Пользователь** (вы - **Resource Owner**) разрешает приложению доступ к своим данным. Google спрашивает: «Разрешить Spotify доступ к вашему email?» → вы соглашаетесь.
3. **Приложение** (которому вы даете доступ, например, Spotify) получает authorization code.
4. **Приложение** обменивает authorization code на access token. Google выдает Spotify **access token.**&#x20;
5. **Приложение** использует access token для доступа к ресурсам.

**Основные роли**

* **Resource Owner** — пользователь (вы).
* **Client** — приложение, которому вы даете доступ (например, Spotify).
* **Authorization Server** — сервис, выдающий токены (например, Google).
* **Resource Server** — сервис, хранящий данные (например, Google Диск).

Authorization Code - это один из методов. Есть 4 метода получение токена (**типы grant**):

* **Authorization Code:**\
  Используется для веб-приложений.
* **Implicit:**\
  Упрощенный способ для одностраничных приложений (не рекомендуется).
* **Client Credentials:**\
  Используется для машинного взаимодействия (без участия пользователя).
* **Password:**\
  Прямая передача логина и пароля (не рекомендуется).
