JavaScript

Реализация авторизации на js

желательно без фреймворков, хочу сделать ручками авторизацию, посмотреть +- как это работает. Пусть это будет простейший пример, не самый продвинутый, мне просто пощупать. Посоветуйте что почитать, посмотреть...
  1. На первом этапе нужно пройти аутентификацию: клиент отправляет логин и пароль, сервер проверяет правильность введенных данных. Тут важно, чтобы логин и пароль не узнал злоумышленник. Поэтому в базе всегда хранится не сам пароль, а хеш, например мд5(логин + пароль + соль). Клиент в запросе тоже может передавать зашифрованный хеш, но так как https все шифрует, то можно обычной html формой обойтись, которая отправит запрос без javaScript'а
  2. После проверки логина-пароля сервер отправляет клиенту метку (специальную строку), который клиент будет отправлять в каждом следующем запросе. Сервер прочитав метку из запроса, будет знать, от кого он пришел. Меткой не может быть id пользователя, потому что злоумышленник может подставлять id-шники много раз и угадать нужный. Поэтому сервер использует для метки зашифрованные данные. Есть разные форматы таких зашифрованных данных: JWT, авторизация формами и т.д.
  3. Клиент отправил логин-пароль, получил метку. Теперь в каждом запросе нужно её отправлять серверу. В javaScript'е обычно хранят метку в локальном хранилище: localStorage.setItem('token', value) и при отправке запроса засовывают в заголовок. Но также как и с формами, есть специальный механизм cookies, который заставляет браузер делать всю работу без javascript. Сервер передаёт метку не в теле запроса, а в cookies и браузер сам передает cookies при следующих запросах.

    Теперь как реализовать: на сервере нужен один эндпоинт принимающий запросы post /login там проверяешь логин-пароль и возвращаешь метку - данные пользователя id, имя и т.д. закодированные в jwt (библиотеки для каждой платформы есть). Нужны также другие эндпоинты, доступные только авторизованному пользователю. В них должна быть метка - jwt, которую раскодируешь и выясняешь, кто это твой пользователь. Если метки нет или произошла ошибка при раскодировании, то возвращаешь ошибку 401 (не авторизован).
    Самое главное, это серверная часть. Если она сделана, то проверять можно каким-нибудь постманом. А в зависимости как у тебя клиентская часть устроена, голый html, обычный javascript, фреймворки вроде React, Angular или вообще это мобильное приложение, то реализация будет разной.
Арсен Шаханов
Арсен Шаханов
997
Лучший ответ
Сергей Михнович Спасибо за подробное объяснение!
Мне фронтенд часть не важна абсолютно, с ней не должно проблем возникать, js везде один и тот же, fetch запросы одни и те же. Думаю принцип мне теперь точно понятен. Я просто не знаю как именно все это делать, как правильно организовать взаимодействие с бд и тому подобное...
Сергей Михнович Вот вопрос, например, при регистрации, логи и пароль записывается в БД, генерируем хеш который возвращаем пользователю и сохраняем в ls или в куки. А если с другого устройства он хочет войти? Там ведь нет сохраненного хеша?
Сергей Михнович
Тут важно, чтобы логин и пароль не узнал злоумышленник. Поэтому в базе всегда хранится не сам пароль, а хеш, например мд5(логин + пароль + соль).
Почему именно так? Можно перехватить логин и пароль что ли как то? Объясните этот момент поподробнее пожалуйста
Арсен Шаханов Надо начинать двигаться от простого постепенно добавляя что-то. Сначала сделай работающий механизм авторизации, проверить пароль можно просто сравнив со статическими данными, password=="пароль" && login=="логин". Проверишь постманом, там можно коллекции создавать, очень удобно потом для тестирования. Потом уже работаешь над клиентской частью или над базой данных.

Перехватить можно легко. Если сделаешь простую программу с сокетом, которая слушает 0.0.0.0 и логирует все в консоль, то будешь перехватывать все запросы с твоего компьютера. Https решает проблему и ты увидишь, что сайты с ним зашифрованы и дают абракадабру. К базе данных тоже может получить доступ недобросовестный сотрудник например, записать в блокнотик и пользоваться этими данными в личных целях.
Арсен Шаханов "Вот вопрос, например, при регистрации, логи и пароль записывается в БД, генерируем хеш который возвращаем пользователю и сохраняем в ls или в куки. А если с другого устройства он хочет войти? Там ведь нет сохраненного хеша?"

В базу записывается хеш. Пользователю мы не хеш отправляем, а токен.
Когда заходишь с другого устройства у тебя нет токена, тебя перекидывает на страницу авторизации с логином и паролем. Вводишь логин пароль, по ним сервер снова высчитывает хеш, этот хеш сравнивает с хешом в базе данных и отправляет токен на новое устройство.
Только лишь на frontend авторизации вам не сделать. Или вы хотите на JS делать backend? Обычно для frontend используют html+js, а для бэка используют php.