Size: a a a

Clojure — русскоговорящее сообщество

2021 November 06

AS

Andrey Shuster in Clojure — русскоговорящее сообщество
Спасибо всем за разъяснения.
источник

DL

Dmytro Lispyvnyi '(🌲... in Clojure — русскоговорящее сообщество
seq-и ifn-ят же
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
ну не все же
источник
2021 November 07

NA

Nikolay Artamonov in Clojure — русскоговорящее сообщество
Помогите провалидировать аутентификацию/авторизацию. Для начала хочу получить простое надежное решение. У меня кложурный бэк и cljs spa. Как сейчас у меня это работает:
*  Пользователь вводит свою организацию, телефон, пароль и отправляет форму
* Отправка формы делает запрос POST /api/login С данными из формы
* Бэкенд по переданным данным ищет пользователя и если нашел отвечает его данными и выставляет сессию с айдишником пользователя (http only).

* Клиент получает успешный ответ и я так понимаю в браузер автоматически попадают данные о сессии.
Клиент же не может дотянуться до сессионных данных, так?

* Клиент делает запрос к api за данными и автоматически вместе с запросом (как я понимаю) отправляется на сервер ранее выставленная сессия
* Сервер получает запрос и в миддлваре проверяет что ему пришел запрос содержащий имя пользователя в сессии и пускает его дальше.

Как правильно проверять в миддлваре сессию?

Как понять на клиенте что пользователь аутентифицирован? Если он залогинился,  закрыл браузер и снова его открыл. У клиента же нет доступа из JS к сессии? Нужно дублировать ее в куках?
источник

PP

Pavel Peganov in Clojure — русскоговорящее сообщество
Клиентский JS не дотянется, а клиент в целом – может. Если браузер под его контролем. В DevTools подправит, например.
Так что если и выставлять там user id, неплохо бы его подписывать на сервере способом, который клиенту не будет доступен вообще никак даже при ручном доступе. HMAC'ом каким-нибудь, например, на серверном секрете.

А проверять, что сессия есть, в условиях когда приложение её не видит и не может проверить, можно разве что запросом к серверу. Вернёт 401 – идём оформлять новую.
источник

IG

Ivan Grishaev in Clojure — русскоговорящее сообщество
можно просто в куки положить айдишник пользователя. Куке выставить secure и http-only
источник

NA

Nikolay Artamonov in Clojure — русскоговорящее сообщество
помимо сессии? Но тогда же их клиентом не прочитать? Если пользователь залогинился, закрыл вкладку и открыл снова.
источник

a

alex in Clojure — русскоговорящее сообщество
а что хочется там прочитать? инфа по пользователю все равно отдается обычно другим ендпоинтом дополнительно куда можно всегда сходить, если локалсторадж не нравится. А протухшая кука или нет - просто смотрим хттп коды всех ответов бекенда (либо коды ошибок приложения)
источник

PP

Pavel Peganov in Clojure — русскоговорящее сообщество
Верно, так и задумано — чтобы никакой XSS не мог эту сессию умыкнуть.
источник

NA

Nikolay Artamonov in Clojure — русскоговорящее сообщество
Я хотел сохранить в куке информацию что пользователь залогинен, чтобы приложение когда запускалось не ходило на бэкенд, а взяла из куки инфу и заредиректила на нужную страницу. Обычно так не делают? Лучше сделать на старте запрос типа GET /userinfo и по ответу понять есть ли сессия для этого клиента?
источник

IG

Ivan Grishaev in Clojure — русскоговорящее сообщество
Куки-то в браузере хранятся, в том числе даже если вкладка закрыта
источник

NA

Nikolay Artamonov in Clojure — русскоговорящее сообщество
но до secure и http-only я же не дотянусь
источник

VG

Vladislav Ganshin in Clojure — русскоговорящее сообщество
По самой куке ты все равно не поймешь, валидна она или нет. Запрос на сервер при старте приложения для проверки куки — отличный вариант.
источник

IG

Ivan Grishaev in Clojure — русскоговорящее сообщество
на клиенте кука тебе не нужна. На беке будет эндпроинт типа GET /me, который вернет словарь текущего юзера по куке
источник

PP

Pavel Peganov in Clojure — русскоговорящее сообщество
Так, господа (и дамы?), я тут параллельно общаюсь с Николаем в ЛС 🙂
На случай, если тут присутствует кто-то, кому эта тема тоже интересна, краткое изложение.

Сессию надёжнее всего проставить, положив в куку с HttpOnly+Secure. Но она всё ещё подконтрольна клиенту (любой может сделать curl -H "Cookie: user_id=ктоугодно" …), и потому должна быть доказана сервером — либо через подпись HMAC'ом, либо вообще хранением сопоставления session-id => [чья, когда-истечёт, ...] на сервере.
Николай предложил JWT — да, это вариант. Может, чуточку оверинжиниринг, зато стандартно.

Что до состояния приложения — можно у сервера спросить свойства сессии, типа "чья сессия" и "когда истекает", и положить локально, в доступное приложению хранилище, типа localstorage. И верить этому, пока не возникнут основания сомневаться.
Соответственно, процесс решения при закрытии + перезапуске, "показывать главный экран или экран входа?" очень прост — всегда показываем главный. А если при его рендеринге сервер где-то вернёт 401 — отправляемся на экран входа. А если для его рендеринга не нужны запросы к серверу вовсе — так может, лучше эту проверку отложить и просто работать, пока позарез не потребуется запрос к серверу.
Так закрываются не только случаи "приложение стартует с нуля, сессия могла за это время закончиться", но и случаи "долго работали в приложении, сессия кончилась прямо в процессе".

Во-о-от.
А, и вот это ещё, более подробное руководство по аспектам безопасности этого дела:
https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
источник

NA

Nikolay Artamonov in Clojure — русскоговорящее сообщество
Еще раз спасибо Павлу!)
источник

IG

Ivan Grishaev in Clojure — русскоговорящее сообщество
В ринге куки подписываются автоматом, нужно только ключ задать
источник

KC

Kirill Chernyshov in Clojure — русскоговорящее сообщество
Разве для этого миддлварь не нужно подтягивать?
источник

PP

Pavel Peganov in Clojure — русскоговорящее сообщество
Вот да, я тоже что-то не вижу места под секрет:
https://ring-clojure.github.io/ring/ring.middleware.cookies.html
источник

PP

Pavel Peganov in Clojure — русскоговорящее сообщество
А, понял. Это именно про сессию и её хранение в куках:
https://ring-clojure.github.io/ring/ring.middleware.session.html
https://ring-clojure.github.io/ring/ring.middleware.session.cookie.html (:key)
источник