Как устроена авторизация по паролю в web-приложениях?

Начинаю осваивать web-разработку со стороны backend`а.

Расскажите, пожалуйста, в двух словах как устроена авторизация в web-приложениях? Или дайте хорошую ссылку...

Ситуация примерно следующая:
  • пишу на С++ статический HTTPS-сервер (использую Poco для уменьшения количества велосипедов);
  • сервер должен отдавать html-cтранички (и прочее сопутствующее js-скрипты, css-файлы, картинки и просто произвольные файлы) только авторизованным пользователям;
  • если пользователь не авторизован, то вернуть: 401 Unauthorized
  • учетные данные пользователей хранятся в текстовом файле (чтоб не усложнять работой с базой данных).


сертификаты настроил. просто странички всем кому попало уже выдает.

По идее логин/пароль в открытом виде передаваться и храниться на сервере не должны.

Куками пока не пользовался, но теоретически понимаю это как: некоторый словарь ключ-значение, который клиент каждый раз при запросе передает серверу, но заполняться может и сервером, и клиентом (Это так?).

Как я понял: сервер при проверке учетных данных убеждается, что в текущая сессия "хорошая" и в куки лепит некий ID, а сам этот ID запоминает в списке "хороших". В следующий раз запрос приходит уже с этим ID в куках и повторно логиниться не нужно (Это так?).

Тут подсмотрел, что оптимально использовать для передачи учетных данных HTML-заголовки.

Но как это сделать? И что такое соль? Она хранится в том текстовом файлике? Или она одна общая на сервер? или она генерится на каждый запрос? Или на ответ?

В общем если конкретизировать:
что сделать с логином/паролем перед передачей серверу?
что хранится в текстовом файле с учетными данными?
как устроена процедура проверки на "хорошесть" на сервере?
  • Вопрос задан
  • 2887 просмотров
Решения вопроса 4
@Alexander1705
Обычно разделяют сессии и авторизацию:

Сессия. Чтобы реализовать сессии сервер при первом соединении с клиентом может генерировать некоторый случайный токен и устанавливать его в куки. Тут важно, что куки должны передаваться по защищённому каналу (HTTPS). Таким образом можно сохранять некоторую информацию о сессии в базе данных или же в самих куки, но тогда нужно подписывать куки, чтобы пользователь не мог их изменять.
В любом случае, сервер будет хранить информацию о активных сессиях в БД.
Подписать куки можно, например, добавив в них помимо нужной вам информации какой-нибудь HMAC.

Авторизация. Сервер никогда не хранит пароли. В базе данных хранят логин и хеш пароля (на самом деле нет). Для авторизации пользовтель передаёт логин и пароль (HTTPS). Сервер вычисляет хеш от пароля и, если он совпадает, сессия помечается как авторизованная.

Соль. Теперь представим, что вы действительно храните логин и хеш пароля в таблице:
login | pass_hash
------+----------
vasya | 4B32E1C...

В идеальном мире это бы неплохо работало. Но в реальном мире 90% ваших пользователей будут иметь пароль вида 12345, password, password123, etc. Соответственно в базе данных будет много одинаковых хешей и злоумышленнику не составит труда быстро подобрать пароли большинства ваших пользователей.
Для этого для каждого пользователя сервер сохраняет некоторые уникальные случайные данные (соль). А вместо хеша пароля хранится hash(pass + salt).
login | salt   | hash
------+--------+-----
vasya | 4B3... | 2A3B9...

Таким образом усложняется перебор паролей по словарю.

Хеш. Возможно вы где-то видели или слышали про MD5. Так вот, MD5 на сегодняшний день не является надёжной криптографической хеш функцией и даже если вы примените MD5 сто или тысячу раз, это не сильно изменит ситуацию. На сегодняшний день рекомендуется использовать SHA-2 или SHA-3.

P. S. Соль и токены обязательно должны быть сгенерированы с помощью CSPRNG.
Ответ написан
@Vasiliy_M
Достали советчики, постоянно толкающие слово "сессия" в контексте вопросов об авторизации/аутентификации.
И то и другое вполне возможно можно реализовать без сессий.
Сессии вообще для другого придуманы.
Ответ написан
devalone
@devalone
̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
Обычно делают так: есть база данных с таблицей пользователей со следующей структурой
id username password
где id - primary key(целочисленное значение уникальное для каждого пользователя)
username понятно
password - хеш пароля, причём к этому хешу добавляется соль, общая для всей базы(хранить где-нибудь в конфиге приложения, чтоб при доступе к базе её было не найти) и какая-нибудь для пользователя, чтоб у разных пользователей пароль qwerty превращался в разные хеши.
И также таблица сессий.
session_key expiration_time user_id
session_key рандомная строка(например Ku0peepia3ialete3uawai9oK3Koh2ni), которая хранится в куках пользователя
expiration_time timestamp когда сессия заканчивается(важно на банковских приложениях например)
user_id - id пользователя, которому принадлежит сессия.
Также можно добавить другие данные, как например ip, user-agent и т.д.

Когда пользователь ввёл логин и пароль в форму и нажал "войти", на сервер отправляется POST запрос с логином и паролем, сервер принимает его, хеширует пароль и проверяет в базе, есть ли такая пара, если есть, создаётся сессия и возвращается пользователю в куках(хедер Set-Cookie), клиент устанавливает их себе и при следующих запросах отправляет сессию в хедере Cookie, либо берётся та, которую отправил пользоваль и привязывается к аккаунту. Когда пользователь заходит в админку, сервер смотрит, есть ли такая сессия и имеет ли права на доступ в админку её владелец, если нет, то возвращает ошибку.
Ответ написан
@Barmunk
Как насчет jwt? stateless решение, нигде не нужно хранить сессии, сервер один раз выдал на определеннее время и забыл, а пользователь его уже продлевает по мере необходимости? Записывает там в куки или куда хотите
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
AlexanderYudakov
@AlexanderYudakov
C#, 1С, Android, TypeScript
Аутентификация по паролям — позапрошлый век.

В той-же статье, на которую вы дали ссылку, прошу обратить внимание на раздел "Аутентификация по токенам".

ВКонтакте, Facebook, Яндекс, Google, Mail.ru и др. — выберите себе провайдера учетных записей по душе и не нужно париться вам с хранением и передачей паролей, а пользователям — с придумыванием этих паролей, их забыванием, восстановлением, вводом с клавиатуры и прочим геморроем.

Наберите в поисковике: oauth <мой любимый провайдер>, и получите подробную инструкцию, как это реализовать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы