Как осуществляется процесс авторизации с использованием пин-кода?

У меня есть система авторизации и регистрации, которая использует почту и пароль, а также JWT для управления сессиями. Я хотел бы добавить возможность авторизации с использованием пин-кода, но не совсем понимаю, как это правильно реализовать. Как осуществляется процесс работы с пин-кодом? Правильно ли я понимаю, что окно для ввода пин-кода появляется, когда срок действия токена истекает, и после введения пин-кода происходит обновление токена? В качестве примера можно рассмотреть веб-версию т-банка, где авторизация после входа осуществляется через пин-код через определенное время.
  • 25 декабря 2024 г. 20:14
Ответы на вопрос 3
Процесс авторизации с использованием пин-кода можно реализовать следующим образом. Давайте разберем основные шаги, как это может работать в системе, использующей JWT для управления сессиями.

### Общая архитектура

1. **Регистрация пользователя:** При регистрации пользователь создает учетную запись с адресом электронной почты и паролем. Если вы решили использовать пин-код, возможно, потребуется дополнительно запросить его у пользователя (например, на этапе первой авторизации).

2. **Авторизация:** Пользователь вводит свои учетные данные (имя пользователя и пароль). Если они корректны, вы выдаете JWT и, возможно, пин-код. Пин-код может сохраняться в зашифрованном виде в базе данных.

3. **Сессия и срок действия токена:** Пользователь работает в приложении с действующим токеном. JWT может иметь срок действия, и при истечении этого срока (например, через 15-30 минут) вы можете предложить пользователю ввести пин-код для продолжения работы.

### Процесс работы с пин-кодом

1. **Истечение токена:** Когда срок действия JWT истекает, клиентское приложение (веб или мобильное) обнаруживает это по ответу сервера (например, 401 Unauthorized) и инициирует процесс повторной авторизации.

2. **Запрос пин-кода:** Вместо того чтобы повторно запрашивать адрес электронной почты и пароль, приложение предлагает пользователю ввести пин-код. Это может происходить через всплывающее окно или отдельную страницу, в зависимости от интерфейса.

3. **Проверка пин-кода:** Пользователь вводит пин-код, и это значение отправляется на сервер. Сервер проверяет его с тем, что хранится в базе данных (обычно в зашифрованном виде). Если пин-код совпадает, сервер может выдать новый JWT.

4. **Выдача нового токена:** Если пин-код верный, сервер создает новый JWT и отправляет его клиентскому приложению. Теперь пользователь может продолжить работу.

5. **Обработка ошибок:** Если пин-код введен неверно, сервер отправляет соответствующий ответ, и клиент может уведомить пользователя о необходимости повторной попытки ввода пин-кода.

### Рекомендации по безопасности

- **Шифрование пин-кода:** Храните пин-коды в зашифрованном виде. Используйте алгоритмы хеширования, такие как bcrypt, чтобы защитить их.

- **Ограничение попыток:** Ограничьте количество попыток ввода пин-кода, чтобы избежать брутфорс-атак. После нескольких неудачных попыток можно временно заблокировать возможность вводить пин-код на короткий срок.

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

### Пример реализации

1. **JWT** выдается на этапах аутентификации:

```javascript
const jwt = require("jsonwebtoken");

// При успешной аутентификации
const token = jwt.sign({ userId: user.id }, secretKey, { expiresIn: "30m" });
```

2. **Проверка пин-кода:**

```javascript
app.post("/verify-pin", (req, res) => {
  const { pin } = req.body;
  // Проверяем пин-код в базе данных
  if (isValidPin(pin)) {
    const newToken = jwt.sign({ userId: user.id }, secretKey, { expiresIn: "30m" });
    res.json({ token: newToken });
  } else {
    res.status(401).json({ error: "Invalid PIN code." });
  }
});
```

Этот процесс предоставляет пользователю простой способ продолжения работы без повторной аутентификации с вводом почты и пароля при каждом истечении токена.
По уму авторизация по PIN это то же самое, что авторизация по ключу, но для чтения ключа и передачи данных авторизации нужен PIN код вместо пароля. Отличие принципиальное в том, что при неудачном наборе PIN несколько раз (например 5 раз) PIN блокируется, и для доступа к ключу нужен пароль. 
Так например работает авторизация в Windows, но я что-то ни разу не встречал такого для доступа к сайтам. Наверное в силу того, на клиенте это надо реализовать программно и защитить как то этот механизм на уровне системы. Ну, например Firebase Authentication такой опции не предлагает.
Вы точно не путаете двухфакторку с пин защитой ? 

Сперва стоит понять нужно ли что-то подобное для вашего сайта.
Если клиенты вашего сайта вынуждены работать с ним с пк, к которому может подойти посторонний человек.
Например, вы написали CRM для сотрудников торгового зала в магазине.
Но даже в таком случае вместо пина можно, по таймауту неактивности (отсутвия запросов к серверу).
Через JS вывести заглушку. А при попытке F5 (рефреша страницы).
показывать кастомизированную форму логина (Типа Вы такой-то такойтович) введите свой пароль. или войдите под другим логином.

Пин доступ все же для устройств, которые всегда с тобой. И только на короткое время выпускаются из вида.
Если же все таки хочется его прикрутить, то свяжи с сессионной кукой.

Кука ставится например на несколько дней. Каждый запрос к бакенду обновляет поле lastAccessTime в таблице сессий. Тогда если прошло больше (условно 15 минут), то бакенд вместо запрошенной страницы отдает форму ввода пин кода. Совпал - обновляем поле. Нет - считаем попытки. Исчерпал удаляем эту сессию - редириктим на обычный логин.
Похожие вопросы