Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Добавить сваггер для эндпойнтов авторизации #77

Closed
birthdaysgift opened this issue Jun 25, 2023 · 1 comment · Fixed by #85
Closed
Assignees

Comments

@birthdaysgift
Copy link
Member

birthdaysgift commented Jun 25, 2023

Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики странице (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.

@birthdaysgift birthdaysgift self-assigned this Jul 6, 2023
birthdaysgift added a commit that referenced this issue Jul 6, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 6, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 6, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 6, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 6, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 6, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 9, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 10, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 13, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 13, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
@birthdaysgift
Copy link
Member Author

Дублирую текст статьи по авторизации, на случай если ссылка в описании тикета станет невалидной.


Аналитика. Авторизация

Эта статья содержит описание основных концепций, применяемых для авторизации в современном программировании. Многие технические детали специально пропущены, т.к. цель этого описания в том, чтобы дать понимание самой идеи, для чего используются те или иные подходы и какие проблемы они решают. Если будет необходимость в более подробном описании деталей технической реализации, то для этого можно будет завести отдельную статью.

Описание начинается от самых простых проблем, которые даже могут показаться странными, т.к. эти проблемы обычно сразу решены по умолчанию, поэтому у разработчиков подобные вопросы могут даже не возникать. Но с каждой новой проблемой, совокупность всех используемых решений будет приближаться к современной реализации авторизации используемой в современных системах.


Проблема

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

Решение

Перед совершением каого-либо действия пользователь предоставляет системе свой логин и пароль, клиентское приложение отправляет их на сервер, где сервер проверяет существует ли такой пользователь в базе данных и есть ли у него право на выполнение запрашиваемого действия.

Результат

Система сможет идентифицировать пользователя и проверять его права, а пользователь сможет совершать действия в системе от своего имени.


Проблема

Пользователь не хочет вводить логин и пароль перед каждым действием, которое он совершает в системе.

Решение

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

Результат

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


Проблема

Уникальный идентификатор может быть скомпрометирован (украден) и использоваться злоумышленниками, которые будут выполнять действия в системе от имени пользователя.

Решение

Ограничить срок жизни этого уникального идентификатора, например до 1 дня. При создании этого короткоживущего идентификатора, сервер будет сохранять в базе данных дату, до которой этот идентификатор будет считаться валидным. Таким образом каждый раз когда пользователь выполняет какое-либо действие в системе, клиентское приложение передаёт запрос на сервер с использованием короткоживущиего идентификатора, сервер будет проверять его срок, и если срок истёк, то идентификатор стирается из базы, и пользователю нужно снова вводить логин и пароль для получения нового идентификатора.

Результат

Если идентификатор будет украден, то злоумышленники смогут работать от имени пользователя не дольше одного дня (время жизни идентификатора), после этого они попадут на форму логина, и поскольку логин и пароль пользователя они не знают, то дальше работать не смогут.


Проблема

Пользователь не хочет вводить логин и пароль каждый раз, когда истекает его короткоживущий идентификатор.

Решение

Вместе с этим идентификатором также отправлять второй уникальный идентификатор, который будет иметь более долгий срок жизни, например 1 месяц. Долгоживущий идентификатор будет использоваться для обновления короткоживущего идентификатора. Т.е. после того как пользователь входит в систему с помощью логина и пароля, клиентское приложения получает от сервера два идентификатора - короткоживущий и долгоживущий. Клиентское приложение будет отправлять короткоживущий идентификатор во всех запросах к серверу, для проверки прав пользователя на совершение какого-либо действия. Если его срок жизни истекает (он становится невалидным), то клиентское приложение отправялет особый запрос в котором передаёт долгоживущий идентификатор, и если он валидный, то сервер выдаёт в ответ новый короткоживущий идентификатор, который будет действовать ещё один день.

Результат

Пользователю не придётся вводить логин и пароль каждый раз когда истекает срок короткоживущего идентификатора - обновлением короткоживущего токена заниматься клиентское приложение.


Проблема

  1. Пользователю нужно вводить логин и пароль каждый месяц (срок долгоживущего идентификатора).

  2. Долгоживущий идентификатор может быть скомпрометирован и использоваться злоумышлениками, чтобы обновлять короткоживущие идентификаторы в течение месяца и всё это время выполнять действия в системе от имени пользователя.

Решение

При обновлении короткоживущего идентификатора обновлять также и долгоживущий. Т.е. при истечении срока короткоживущего идентификатора, клиентское приложение передаёт серверу валидный долгоживущий идентификатор и получает от него два новых - свежий короткоживущий, и свежий долгоживущий.

Результат

  1. Пользователю не придётся вводить логин и пароль каждый месяц до тех пор пока он регулярно работает в системе. Т.к. при выполнении пользователем любого действия в системе оба его идентификатора будут обновляться. Если же он за месяц не совершил никаких действий в системе, то его долгоживущий идентификатор оказывается истекшим, и пользователю придётся ввести логин и пароль.

  2. Даже если долгоживущий идентификатор будет скомпрометирован, то после того как приложение настоящего пользователя обновит идентификаторы, то скомпрометированный долгоживущий идентификатор станет невалидным, т.к. система выдала пользователю другой долгоживущий и удалила старый из базы данных. И поскольку долгоживущий идентификатор злоумышленника стал невалидным, злоумышленнику придётся вводить логин и пароль, чтобы получить новые идентификаторы.

    Если же например злоумышленник успел обновить идентификаторы, по украденному долгоживущему идентификатору до того как это сделал настоящий пользователь, то долгоживущий идентификатор настоящего пользователя станет невалидным для системы, и она попросить его ввести логин и пароль. А так как пользователь знает свой логин и пароль, то он получит свежие идентификаторы, а украденный идентификатор злоумышленника станет невалидным и злоумышленнику также придётся вводить логин и пароль, а он их не знает. Таким образом злоумышленник сможет работать с системой по скомпрометированному идентификатору только до тех пор, пока реальный пользователь не попробует выполнить какое-либо действие в системе и не введёт логин и пароль заново, после этого идентификаторы злоумышленника станут невалидными.


Проблема

Пользователь работает с нашей системой с двух разных устройств (например с двух разных компьютеров - "A" и "B"). Пользователь работает за компьютером "A". Клиентское приложения компьютера "A" получает от сервера два идентификатора short_A и long_A. Пользователь переходит за компьютер "B". Клиентское приложение компьютера "B" получает от сервера два других идентификатора - short_B и long_B. Как только сервер выдал компьютеру "B" долгоживущий идентификатор long_B, то долгоживущий идентификатор компьютера "A" (long_A) стал невалидным, и пользователю придётся заново вводить свой логин и пароль на компьютере "A".

Решение

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

Результат

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


Авторизация с использованием стороннего сервиса

Ниже идёт отдельный раздел отвечающий за регистрацию/логин на стороннем сервисе. Проблемы описанные в них могут быть пропущены, и тогда мы получим реализацию OAuth в рамках одного (нашего) сервиса, без помощи сторонних авторизующих ресурсов.

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


Проблема

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

Решение

Вместо заполнения формы логина в нашей системе, мы можем редиректить пользователя в сервис, в котором он уже зарегистрирован, где он пройдёт процедуру логина и получит оттуда короткоживущий и долгоживущий идентификаторы, которые используются в том сервисе. В нашей системе мы свяжем эти идентификаторы с пользователем и будем знать, что каждый запрос содержащий этот идентификатор был отправлен именно этим пользователем. В случае если срок идентификатора истекает, то для его обновления мы обращаемся к тому сервису, от которого он был получен.

Результат

Пользователь может помнить только логин и пароль от авторизующего сервиса и через него попадать в нашу систему (и в другие системы, которые прошли интеграцию с этим авторизующим сервисом).


Проблема

Наш сервис должен быть уверен в том, что идентификаторы были получены именно из того сервиса, на который мы редиректили пользователя.

Решение

На этапе интеграции нашей системы с таким сторонним сервисом, этот сервис должен передать нам секретный ключ, который будет использоваться для подписания идентификатора на их стороне, а мы в свою очередь с помощью этого ключа на своей стороне сможем проверить эту подпись. Т.к. этот ключ известен только нам и тому сервису, с которым мы интегрируемся, то злоумышленники не смогут подделать подпись этого идентификатора, а значит, проверив подпись, мы можем быть уверены, что идентификатор пришёл из правильного источника и не был подделан по пути.

Результат

Мы всегда будем понимать, что идентификатор получен от конкретного стороннего сервиса после того как пользователь прошёл в нём процедуру логина.

birthdaysgift added a commit that referenced this issue Jul 16, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 23, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 24, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 24, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 26, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 26, 2023
Перед тем как приступить к реализации эндпойнтов авторизации, необходимо продумать их архитектуру и создать контракты.

Было принято решение реализовать упрощённую реализацию OAuth своими силами, чтобы лучше разобраться в работе протокола. Описание концепций, которые мы планируем реализовать находится на отдельной вики [странице](https://github.com/week-password/wisher/wiki/%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0.-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (если эта ссылка, по какой-то причине отвалилась, то смотри комментарии к тикету #77 на гитхабе).

В рамках этой задачи необходимо продумать архитектуру эндпойнтов авторизации и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Jul 30, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77), мы забыли добавить поле description, которое пользователь может заполнить на экране регистрации.

В рамках этой задачи необходимо добавить поле description в сваггер эндпойнта регистрации, а также прописать его в схему `_NewProfile`, которая используется для описания входных данных профиля при регистрации.
birthdaysgift added a commit that referenced this issue Jul 31, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77), мы забыли добавить поле description, которое пользователь может заполнить на экране регистрации.

В рамках этой задачи необходимо добавить поле description в сваггер эндпойнта регистрации, а также прописать его в схему `_NewProfile`, которая используется для описания входных данных профиля при регистрации.
birthdaysgift added a commit that referenced this issue Aug 8, 2023
После того как была разработана архитектура эндпойнтов авторизации (#77), можно приступить к разработке архитектуры эндпойнтов для работы с Аккаунтом пользователя.

В рамках этой задачи необходимо разработать архитектуру эндпойнтов Аккаунта и добавить определния сваггера.

**Особенности реализации**

Т.к. роутинг на фронте работает через логин юзера, например `http://wlss.com/john_doe/friends`, в то время как REST апишка бэка использует айди, например `GET /accounts/42/friends`, то может возникнуть ситуация, когда фронт не знает айди аккаунта, и как следствие не может делать запросы на бэк. Например, если юзер просто перейдёт по прямой ссылке `http://wlss.com/john_doe/friends`, то фронт будет знать только логин юзера, но не будет знать его айди, и следовательно не сможет отправлять запросы на бэк.

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

Таким образом у нас будет два эндпойнта для получения информации об аккаунте - один обменивает логин юзера на айди, при этом проверка прав позволяет любому юзеру зарегистрированному в системе получить айди любого другого пользователя по его логину. Второй эндпойнт возвращает полную информацию по аккаунту пользователя, при этом проверка прав этого эндпойнта позволяет юзерам получать информацию только по своему аккаунту.
birthdaysgift added a commit that referenced this issue Aug 9, 2023
После того как была разработана архитектура эндпойнтов авторизации (#77), можно приступить к разработке архитектуры эндпойнтов для работы с Аккаунтом пользователя.

В рамках этой задачи необходимо разработать архитектуру эндпойнтов Аккаунта и добавить определния сваггера.

**Особенности реализации**

Т.к. роутинг на фронте работает через логин юзера, например `http://wlss.com/john_doe/friends`, в то время как REST апишка бэка использует айди, например `GET /accounts/42/friends`, то может возникнуть ситуация, когда фронт не знает айди аккаунта, и как следствие не может делать запросы на бэк. Например, если юзер просто перейдёт по прямой ссылке `http://wlss.com/john_doe/friends`, то фронт будет знать только логин юзера, но не будет знать его айди, и следовательно не сможет отправлять запросы на бэк.

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

Поскольку на данный момент согласно дизайнам MVP, мы не планируем нигде выводить полную информацию об аккаунте пользователя, то сейчас нам достаточно только одного эндпойнта, который обменивает логин на айди.

Если в будущем возникнет необходимость получать полную информацию об аккаунте, то для этого придётся создать отдельный эндпойнт. Таким образом у нас будет два эндпойнта для получения информации об аккаунте - один обменивает логин юзера на айди, при этом проверка прав позволяет любому юзеру зарегистрированному в системе получить айди любого другого пользователя по его логину. Второй эндпойнт возвращает полную информацию по аккаунту пользователя, при этом проверка прав этого эндпойнта позволяет юзерам получать информацию только по своему аккаунту.
birthdaysgift added a commit that referenced this issue Nov 15, 2023
После добавления сваггера для эндпойнтов авторизации (#77), необходимо добавить сваггер для эндпойнтов работающих с файлами. Это необходимо для работы с аватараками пользователей.

В рамках этой задачи необходимо разработать архитектуру и добавить сваггер для эндпойнтов, работающих с файлами.
birthdaysgift added a commit that referenced this issue Nov 15, 2023
После того как была разработана архитектура эндпойнтов авторизации (#77) и профиля (#95), можно приступить к разработке архитектуры эндпойнтов для работы с желаниями пользователя.

В рамках этой задачи необходимо разработать архитектуру эндпойнтов Желания и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Nov 17, 2023
После того как была разработана архитектура эндпойнтов авторизации (#77) и профиля (#95), можно приступить к разработке архитектуры эндпойнтов для работы с желаниями пользователя.

В рамках этой задачи необходимо разработать архитектуру эндпойнтов Желания и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Nov 17, 2023
После того как была разработана архитектура эндпойнтов авторизации (#77) и профиля (#95), можно приступить к разработке архитектуры эндпойнтов для работы с желаниями пользователя.

В рамках этой задачи необходимо разработать архитектуру эндпойнтов Желания и добавить определения сваггера.
birthdaysgift added a commit that referenced this issue Nov 17, 2023
После добавления сваггера для эндпойнтов авторизации (#77), необходимо добавить сваггер для эндпойнтов работающих с файлами. Это необходимо для работы с аватараками пользователей.

В рамках этой задачи необходимо разработать архитектуру и добавить сваггер для эндпойнтов, работающих с файлами.
birthdaysgift added a commit that referenced this issue Nov 18, 2023
После добавления сваггера для эндпойнтов авторизации (#77), необходимо добавить сваггер для эндпойнтов работающих с файлами. Это необходимо для работы с аватараками пользователей.

В рамках этой задачи необходимо разработать архитектуру и добавить сваггер для эндпойнтов, работающих с файлами.
birthdaysgift added a commit that referenced this issue Nov 19, 2023
После добавления сваггера для эндпойнтов авторизации (#77), необходимо добавить сваггер для эндпойнтов работающих с файлами. Это необходимо для работы с аватараками пользователей.

В рамках этой задачи необходимо разработать архитектуру и добавить сваггер для эндпойнтов, работающих с файлами.

---

В процессе реализации были приняты следующие решения:

Кроме uuid фала, мы также решили сохранять в бд дополнительные сведения о загружаемых файлах, а именно:

- `name` - полное имя файла, например `"john_doe.png"`
- `size` - размер файла в байтах, например `1_048_576`
- `extension` - разрешение файла, например `"png"`
- `mime_type` - MIME-тип данных, например `"image/png"`

Именно поэтому мы добавили эту информацию в респонз эндпойнта на загрузку нового файла.

Возможно, в будущем эта информация окажется нам не нужна, и мы удалим её из бд, но на данный момент было принято решение добавить её, т.к. если её не будет в бд и в какой-то момент мы поймём, что она всё-таки нам нужна, то её будет довольно трудно восстановить - придётся проводить миграцию, в которой нужно будет брать все файлы из minio и вычислять эти параметры для каждого файла, чтобы записать их в бд для уже существующих фалов.
birthdaysgift added a commit that referenced this issue Nov 19, 2023
После добавления сваггера для эндпойнтов авторизации (#77), необходимо добавить сваггер для эндпойнтов работающих с файлами. Это необходимо для работы с аватараками пользователей.

В рамках этой задачи необходимо разработать архитектуру и добавить сваггер для эндпойнтов, работающих с файлами.

---

В процессе реализации были приняты следующие решения:

Кроме uuid фала, мы также решили сохранять в бд дополнительные сведения о загружаемых файлах, а именно:

- `name` - полное имя файла, например `"john_doe.png"`
- `size` - размер файла в байтах, например `1_048_576`
- `extension` - разрешение файла, например `"png"`
- `mime_type` - MIME-тип данных, например `"image/png"`

Именно поэтому мы добавили эту информацию в респонз эндпойнта на загрузку нового файла.

Возможно, в будущем эта информация окажется нам не нужна, и мы удалим её из бд, но на данный момент было принято решение добавить её, т.к. если её не будет в бд и в какой-то момент мы поймём, что она всё-таки нам нужна, то её будет довольно трудно восстановить - придётся проводить миграцию, в которой нужно будет брать все файлы из minio и вычислять эти параметры для каждого файла, чтобы записать их в бд для уже существующих фалов.
birthdaysgift added a commit that referenced this issue Nov 19, 2023
После добавления сваггера для эндпойнтов авторизации (#77), необходимо добавить сваггер для эндпойнтов работающих с файлами. Это необходимо для работы с аватараками пользователей.

В рамках этой задачи необходимо разработать архитектуру и добавить сваггер для эндпойнтов, работающих с файлами.

---

В процессе реализации были приняты следующие решения:

Кроме uuid фала, мы также решили сохранять в бд дополнительные сведения о загружаемых файлах, а именно:

- `name` - полное имя файла, например `"john_doe.png"`
- `size` - размер файла в байтах, например `1_048_576`
- `extension` - разрешение файла, например `"png"`
- `mime_type` - MIME-тип данных, например `"image/png"`

Именно поэтому мы добавили эту информацию в респонз эндпойнта на загрузку нового файла.

Возможно, в будущем эта информация окажется нам не нужна, и мы удалим её из бд, но на данный момент было принято решение добавить её, т.к. если её не будет в бд и в какой-то момент мы поймём, что она всё-таки нам нужна, то её будет довольно трудно восстановить - придётся проводить миграцию, в которой нужно будет брать все файлы из minio и вычислять эти параметры для каждого файла, чтобы записать их в бд для уже существующих фалов.
birthdaysgift added a commit that referenced this issue Nov 19, 2023
После добавления сваггера для эндпойнтов авторизации (#77), необходимо добавить сваггер для эндпойнтов работающих с файлами. Это необходимо для работы с аватараками пользователей.

В рамках этой задачи необходимо разработать архитектуру и добавить сваггер для эндпойнтов, работающих с файлами.

---

В процессе реализации были приняты следующие решения:

Кроме uuid фала, мы также решили сохранять в бд дополнительные сведения о загружаемых файлах, а именно:

- `name` - полное имя файла, например `"john_doe.png"`
- `size` - размер файла в байтах, например `1_048_576`
- `extension` - разрешение файла, например `"png"`
- `mime_type` - MIME-тип данных, например `"image/png"`

Именно поэтому мы добавили эту информацию в респонз эндпойнта на загрузку нового файла.

Возможно, в будущем эта информация окажется нам не нужна, и мы удалим её из бд, но на данный момент было принято решение добавить её, т.к. если её не будет в бд и в какой-то момент мы поймём, что она всё-таки нам нужна, то её будет довольно трудно восстановить - придётся проводить миграцию, в которой нужно будет брать все файлы из minio и вычислять эти параметры для каждого файла, чтобы записать их в бд для уже существующих фалов.
birthdaysgift added a commit that referenced this issue Nov 24, 2023
После добавления сваггера для эндпойнтов авторизации (#77), необходимо добавить сваггер для эндпойнтов работающих с файлами. Это необходимо для работы с аватараками пользователей.

В рамках этой задачи необходимо разработать архитектуру и добавить сваггер для эндпойнтов, работающих с файлами.

---

В процессе реализации были приняты следующие решения:

Кроме uuid фала, мы также решили сохранять в бд дополнительные сведения о загружаемых файлах, а именно:

- `name` - полное имя файла, например `"john_doe.png"`
- `size` - размер файла в байтах, например `1_048_576`
- `extension` - разрешение файла, например `"png"`
- `mime_type` - MIME-тип данных, например `"image/png"`

Именно поэтому мы добавили эту информацию в респонз эндпойнта на загрузку нового файла.

Возможно, в будущем эта информация окажется нам не нужна, и мы удалим её из бд, но на данный момент было принято решение добавить её, т.к. если её не будет в бд и в какой-то момент мы поймём, что она всё-таки нам нужна, то её будет довольно трудно восстановить - придётся проводить миграцию, в которой нужно будет брать все файлы из minio и вычислять эти параметры для каждого файла, чтобы записать их в бд для уже существующих фалов.
birthdaysgift added a commit that referenced this issue Nov 24, 2023
После добавления сваггера для эндпойнтов авторизации (#77), необходимо добавить сваггер для эндпойнтов работающих с файлами. Это необходимо для работы с аватараками пользователей.

В рамках этой задачи необходимо разработать архитектуру и добавить сваггер для эндпойнтов, работающих с файлами.

---

В процессе реализации были приняты следующие решения:

Кроме uuid фала, мы также решили сохранять в бд дополнительные сведения о загружаемых файлах, а именно:

- `name` - полное имя файла, например `"john_doe.png"`
- `size` - размер файла в байтах, например `1_048_576`
- `extension` - разрешение файла, например `"png"`
- `mime_type` - MIME-тип данных, например `"image/png"`

Именно поэтому мы добавили эту информацию в респонз эндпойнта на загрузку нового файла.

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

Также было принято решение не добавлять каких-либо ограничений для имен файлов, по следующим причинам:

1. Ограничения для допустимых имён файлов отличаются на разных системах, и чтобы учесть их все, необходимо проделать значительную работу.

2. Мы предполагаем, что пользователь загружает файл из операционной системы, и поскольку файл существует в его операционной системе, значит имя этого файла не нарушает правил этой операционной системы. Следовательно, предполагаем, что если пользователь смог загрузить файл, то он сможет его и скачать с тем же имененм.
birthdaysgift added a commit that referenced this issue Nov 29, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77) и файла (#108), мы добавили кастомные shared поля для pydantic-схем (src/shared/fields.py), в которых мы расширили стандартные типы данных и добавили более строгие проверки с помощью своих кастомных валидаторов.

Но мы не учли один нюанс - не смотря на то, что наши кастомные поля наследуются от базовых типов, например:
```python
class IntField(int):
    ...
```
при встраивании такого поля в схему
```python
class Foo(pydantic.BaseModel):
    id: IntField
```
пайдентик не будет использовать базовый тип (данном случае `int`) для валидации типа входящего значения. Т.е. например следующий код выполнится без ошибок, если входящее значение пройдёт все проверки наших кастомных валидаторов:
```python
Foo(id="not integer data")
```

Поскольку такое поведение оказалось для нас неожиданным и мы всё таки хотим иметь явные проверки типа входящего значения, то в рамках этой задачи необходимо добавить проверки типов в базовые кастомные поля.
birthdaysgift added a commit that referenced this issue Nov 30, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77) и файла (#108), мы добавили кастомные shared поля для pydantic-схем (src/shared/fields.py), в которых мы расширили стандартные типы данных и добавили более строгие проверки с помощью своих кастомных валидаторов.

Но мы не учли один нюанс - не смотря на то, что наши кастомные поля наследуются от базовых типов, например:
```python
class IntField(int):
    ...
```
при встраивании такого поля в схему
```python
class Foo(pydantic.BaseModel):
    id: IntField
```
пайдентик не будет использовать базовый тип (данном случае `int`) для валидации типа входящего значения. Т.е. например следующий код выполнится без ошибок, если входящее значение пройдёт все проверки наших кастомных валидаторов:
```python
Foo(id="not integer data")
```

Поскольку такое поведение оказалось для нас неожиданным и мы всё таки хотим иметь явные проверки типа входящего значения, то в рамках этой задачи необходимо добавить проверки типов в базовые кастомные поля.
birthdaysgift added a commit that referenced this issue Dec 2, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77) и файла (#108), мы добавили кастомные shared поля для pydantic-схем (src/shared/fields.py), в которых мы расширили стандартные типы данных и добавили более строгие проверки с помощью своих кастомных валидаторов.

Но мы не учли один нюанс - не смотря на то, что наши кастомные поля наследуются от базовых типов, например:
```python
class IntField(int):
    ...
```
при встраивании такого поля в схему
```python
class Foo(pydantic.BaseModel):
    id: IntField
```
пайдентик не будет использовать базовый тип (данном случае `int`) для валидации типа входящего значения. Т.е. например следующий код выполнится без ошибок, если входящее значение пройдёт все проверки наших кастомных валидаторов:
```python
Foo(id="not integer data")
```

Поскольку такое поведение оказалось для нас неожиданным и мы всё таки хотим иметь явные проверки типа входящего значения, то в рамках этой задачи необходимо добавить проверки типов в базовые кастомные поля.
birthdaysgift added a commit that referenced this issue Dec 2, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77) и файла (#108), мы добавили кастомные shared поля для pydantic-схем (src/shared/fields.py), в которых мы расширили стандартные типы данных и добавили более строгие проверки с помощью своих кастомных валидаторов.

Но мы не учли один нюанс - не смотря на то, что наши кастомные поля наследуются от базовых типов, например:
```python
class IntField(int):
    ...
```
при встраивании такого поля в схему
```python
class Foo(pydantic.BaseModel):
    id: IntField
```
пайдентик не будет использовать базовый тип (данном случае `int`) для валидации типа входящего значения. Т.е. например следующий код выполнится без ошибок, если входящее значение пройдёт все проверки наших кастомных валидаторов:
```python
Foo(id="not integer data")
```

Поскольку такое поведение оказалось для нас неожиданным и мы всё таки хотим иметь явные проверки типа входящего значения, то в рамках этой задачи необходимо добавить проверки типов в базовые кастомные поля.
birthdaysgift added a commit that referenced this issue Dec 9, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77), эндпойнт создания аккаунта был добавлен в пакет `auth`.

Тогда казалось, что этот эндпойнт должен быть там, т.к. он будет использоваться в процессе регистрации. Но если посмотреть на этот эндпойнт более внимательно, то окажется, что с точки зрения REST архитектуры этот эндпойнт не имеет ничего общего с авторизацией и аутентификацией. Этот эндпойнт просто создаёт ресурс и при этом не проверяет и не выдаёт никаких прав пользователю. Этот эндпойнт относится к CRUD набору операций, доступных над сущностью акканута, и, следовательно, должен быть перемещён в пакет `account`.

Это также позволит нам убрать из пакета `auth` данные, которые выглядят инородными для этого пакета, например:
- схемы `NewAccount` и `NewProfile`, которые по логике хотелось бы видеть в пакетах `account` и `profile` соответственно
- поле `Password`, которое по нашей DDD модели должно принадлежать сущности Аккаунта, и следовательно находиться в пакете `account`

В рамках этой задачи необходимо перенести эндпойнт создания аккаунта в пакет с эндпойнтами аккаунта.
birthdaysgift added a commit that referenced this issue Dec 9, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77), эндпойнт создания аккаунта был добавлен в пакет `auth`.

Тогда казалось, что этот эндпойнт должен быть там, т.к. он будет использоваться в процессе регистрации. Но если посмотреть на этот эндпойнт более внимательно, то окажется, что с точки зрения REST архитектуры этот эндпойнт не имеет ничего общего с авторизацией и аутентификацией. Этот эндпойнт просто создаёт ресурс и при этом не проверяет и не выдаёт никаких прав пользователю. Этот эндпойнт относится к CRUD набору операций, доступных над сущностью акканута, и, следовательно, должен быть перемещён в пакет `account`.

Это также позволит нам убрать из пакета `auth` данные, которые выглядят инородными для этого пакета, например:
- схемы `NewAccount` и `NewProfile`, которые по логике хотелось бы видеть в пакетах `account` и `profile` соответственно
- поле `Password`, которое по нашей DDD модели должно принадлежать сущности Аккаунта, и следовательно находиться в пакете `account`

В рамках этой задачи необходимо перенести эндпойнт создания аккаунта в пакет с эндпойнтами аккаунта.
birthdaysgift added a commit that referenced this issue Dec 9, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77), эндпойнт создания аккаунта был добавлен в пакет `auth`.

Тогда казалось, что этот эндпойнт должен быть там, т.к. он будет использоваться в процессе регистрации. Но если посмотреть на этот эндпойнт более внимательно, то окажется, что с точки зрения REST архитектуры этот эндпойнт не имеет ничего общего с авторизацией и аутентификацией. Этот эндпойнт просто создаёт ресурс и при этом не проверяет и не выдаёт никаких прав пользователю. Этот эндпойнт относится к CRUD набору операций, доступных над сущностью акканута, и, следовательно, должен быть перемещён в пакет `account`.

Это также позволит нам убрать из пакета `auth` данные, которые выглядят инородными для этого пакета, например:
- схемы `NewAccount` и `NewProfile`, которые по логике хотелось бы видеть в пакетах `account` и `profile` соответственно
- поле `Password`, которое по нашей DDD модели должно принадлежать сущности Аккаунта, и следовательно находиться в пакете `account`

В рамках этой задачи необходимо перенести эндпойнт создания аккаунта в пакет с эндпойнтами аккаунта.
birthdaysgift added a commit that referenced this issue Dec 9, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77), была разработана архитектура авторизации/аутентификации, но как оказалось она содержит несколько недостатков:

- **Параметр `device_id` может вводить в заблуждение.**

  Например в эндпойнтах:
  `DELETE /accounts/{account_id}/tokens/{device_id}`
  `PUT /accounts/{account_id}/tokens/{device_id}/refresh`

  Потребителю апи может показаться, что `device_id` обозначает конкретный физический девайс, через который работает пользователь, но это не так, потому что даже в рамках одного физического устройства, пользователь может иметь несколько разных авторизационных сессий (например из разных браузеров).

  Для решения этой проблемы можно использовать название `session_id` вместо `device_id`. В данном случае, название `session_id` по смыслу подходит гораздо лучше, т.к. обозначает не устройство а всего лишь авторизационную сессию.

- **Токены рассматриваются как дочерний ресурс аккаунта.**

  Например в эндпойнтах:
  `POST /accounts/{account_id}/tokens`
  `DELETE /accounts/{account_id}/tokens/{device_id}`
  `PUT /accounts/{account_id}/tokens/{device_id}/refresh`

   При этом `device_id` (он же `session_id` - см. первую проблему) в данном случае выглядит как дочерний ресурс, что является странным, т.к. не девайс создаётся в рамках существующих токенов, а токены создаются в рамках существующего девайса.

  Эту проблему можно решить (с учетом замены `device_id` -> `session_id`), если связать токены с авторизационной сессией и сделать токены дочерним ресурсом этой сессии.

  Т.е. станет:
  `POST /accounts/{account_id}/sessions`
  `POST /accounts/{account_id}/sessions/{session_id}/tokens`
  `DELETE /accounts/{account_id}/sessions/{session_id}`
  `DELETE /accounts/{account_id}/sessions`

  При этом мы изменили эндпойнт получения свежих токенов так, что теперь он выглядит как создание нового ресурса tokens в рамках конкретной сессии. Что также хорошо согласуется с семантикой REST архитектуры - описание действий (http методы), выполняемых над ресурсами (uri путь).

- **Эндпойнт логина требует `account_id`.**
  Это является технической проблемой апи, т.к. на момент запроса к эндпойнту логина, фронт не владеет информацией об аккаунте, и не может передать соответствующий `account_id`.

  Т.е. на данный момент эндпойнт выглядит следующим образом:
  `/accounts/{account_id}/tokens`

  Эту проблему можно решить (с учетом изменений описанных выше), если представить процедуру входа в систему, как создание новой авторизационной сессии.

  Т.е. эндпойнт будет выглдяеть так:
  `POST /sessions`

- **Эндпойнты принимают токены неконсистентно.**
  На данный момент access токен во всех эндпойнтах принимается через Authorization хедер, но при этом refresh токен, принимается через тело запроса. Эту проблему можно решить если создать отдельные fastapi dependency для валидации и парсинга каждого токена, например `get_access_token` и `get_refresh_token`. Обе они будут получать токен из хедера и возвращать пейлоад соответствующего токена.

- **Пейлоад токенов не зафиксирован в схемах.**
  При этом пейлоад токенов имеет важное значение с точки зрения безопасности. Можно зафиксировать схему пейлоада в виде типа возвращаемого значения из fastapi dependency, которая валидирует, парсит и проверяет токен. Планируемая схема пейлоада для токенов описана ниже.

**Пейлоад access-токена:**

- `account_id` - айди аккаунта пользователя, использующего access-токен.
   Позволит идентифицировать пользователя инициировавшего действие в системе.

- `session_id` - айди авторизационной сессии, с которой связан используемый access-токен.
  Позволит идентифицировать авторизационную сессию в рамках которой пользователь выполняет запрос, а также сделать access-токены уникальными, относительно разных сессий одного и того же пользователя.

- `created_at` - дата и время создания используемого access-токена.
  Позволит проверять expiration time для токена, а также сделать access-токены уникальными, относительно токенов, созданных в разное время в рамках одной и той же сессии - т.е. позволит сделать каждый новый "свежий" токен сессии уникальным.

**Пейлоад refresh-токена:**

- `session_id` - айди авторизационной сессии, с которой связан используемый refresh-токен.
  Позволит идентифицировать авторизационную сессию в рамках которой пользователь выполняет запрос, а также сделать refresh-токены уникальными, относительно разных сессий одно и того же пользователя.

- `created_at` - дата и время создания используемого refresh-токена.
  Позволит проверять expiration time для токена, а также сделать refresh-токены уникальными, относительно токенов, созданных в разное время в рамках одной и той же сессии - т.е. позволит сделать каждый новый "свежий" токен сессии уникальным.

В рамках этой задачи необходимо внести изменения в архитектуру эндпойнтов авторизации/аутентификации, исходя из правок, описанных выше.
birthdaysgift added a commit that referenced this issue Dec 9, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77), была разработана архитектура авторизации/аутентификации, но как оказалось она содержит несколько недостатков:

- **Параметр `device_id` может вводить в заблуждение.**

  Например в эндпойнтах:
  `DELETE /accounts/{account_id}/tokens/{device_id}`
  `PUT /accounts/{account_id}/tokens/{device_id}/refresh`

  Потребителю апи может показаться, что `device_id` обозначает конкретный физический девайс, через который работает пользователь, но это не так, потому что даже в рамках одного физического устройства, пользователь может иметь несколько разных авторизационных сессий (например из разных браузеров).

  Для решения этой проблемы можно использовать название `session_id` вместо `device_id`. В данном случае, название `session_id` по смыслу подходит гораздо лучше, т.к. обозначает не устройство а всего лишь авторизационную сессию.

- **Токены рассматриваются как дочерний ресурс аккаунта.**

  Например в эндпойнтах:
  `POST /accounts/{account_id}/tokens`
  `DELETE /accounts/{account_id}/tokens/{device_id}`
  `PUT /accounts/{account_id}/tokens/{device_id}/refresh`

   При этом `device_id` (он же `session_id` - см. первую проблему) в данном случае выглядит как дочерний ресурс, что является странным, т.к. не девайс создаётся в рамках существующих токенов, а токены создаются в рамках существующего девайса.

  Эту проблему можно решить (с учетом замены `device_id` -> `session_id`), если связать токены с авторизационной сессией и сделать токены дочерним ресурсом этой сессии.

  Т.е. станет:
  `POST /accounts/{account_id}/sessions`
  `POST /accounts/{account_id}/sessions/{session_id}/tokens`
  `DELETE /accounts/{account_id}/sessions/{session_id}`
  `DELETE /accounts/{account_id}/sessions`

  При этом мы изменили эндпойнт получения свежих токенов так, что теперь он выглядит как создание нового ресурса tokens в рамках конкретной сессии. Что также хорошо согласуется с семантикой REST архитектуры - описание действий (http методы), выполняемых над ресурсами (uri путь).

- **Эндпойнт логина требует `account_id`.**
  Это является технической проблемой апи, т.к. на момент запроса к эндпойнту логина, фронт не владеет информацией об аккаунте, и не может передать соответствующий `account_id`.

  Т.е. на данный момент эндпойнт выглядит следующим образом:
  `/accounts/{account_id}/tokens`

  Эту проблему можно решить (с учетом изменений описанных выше), если представить процедуру входа в систему, как создание новой авторизационной сессии.

  Т.е. эндпойнт будет выглдяеть так:
  `POST /sessions`

- **Эндпойнты принимают токены неконсистентно.**
  На данный момент access токен во всех эндпойнтах принимается через Authorization хедер, но при этом refresh токен, принимается через тело запроса. Эту проблему можно решить если создать отдельные fastapi dependency для валидации и парсинга каждого токена, например `get_access_token` и `get_refresh_token`. Обе они будут получать токен из хедера и возвращать пейлоад соответствующего токена.

- **Пейлоад токенов не зафиксирован в схемах.**
  При этом пейлоад токенов имеет важное значение с точки зрения безопасности. Можно зафиксировать схему пейлоада в виде типа возвращаемого значения из fastapi dependency, которая валидирует, парсит и проверяет токен. Планируемая схема пейлоада для токенов описана ниже.

**Пейлоад access-токена:**

- `account_id` - айди аккаунта пользователя, использующего access-токен.
   Позволит идентифицировать пользователя инициировавшего действие в системе.

- `session_id` - айди авторизационной сессии, с которой связан используемый access-токен.
  Позволит идентифицировать авторизационную сессию в рамках которой пользователь выполняет запрос, а также сделать access-токены уникальными, относительно разных сессий одного и того же пользователя.

- `created_at` - дата и время создания используемого access-токена.
  Позволит проверять expiration time для токена, а также сделать access-токены уникальными, относительно токенов, созданных в разное время в рамках одной и той же сессии - т.е. позволит сделать каждый новый "свежий" токен сессии уникальным.

**Пейлоад refresh-токена:**

- `session_id` - айди авторизационной сессии, с которой связан используемый refresh-токен.
  Позволит идентифицировать авторизационную сессию в рамках которой пользователь выполняет запрос, а также сделать refresh-токены уникальными, относительно разных сессий одно и того же пользователя.

- `created_at` - дата и время создания используемого refresh-токена.
  Позволит проверять expiration time для токена, а также сделать refresh-токены уникальными, относительно токенов, созданных в разное время в рамках одной и той же сессии - т.е. позволит сделать каждый новый "свежий" токен сессии уникальным.

В рамках этой задачи необходимо внести изменения в архитектуру эндпойнтов авторизации/аутентификации, исходя из правок, описанных выше.
birthdaysgift added a commit that referenced this issue Dec 9, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77), была разработана архитектура авторизации/аутентификации, но как оказалось она содержит несколько недостатков:

- **Параметр `device_id` может вводить в заблуждение.**

  Например в эндпойнтах:
  `DELETE /accounts/{account_id}/tokens/{device_id}`
  `PUT /accounts/{account_id}/tokens/{device_id}/refresh`

  Потребителю апи может показаться, что `device_id` обозначает конкретный физический девайс, через который работает пользователь, но это не так, потому что даже в рамках одного физического устройства, пользователь может иметь несколько разных авторизационных сессий (например из разных браузеров).

  Для решения этой проблемы можно использовать название `session_id` вместо `device_id`. В данном случае, название `session_id` по смыслу подходит гораздо лучше, т.к. обозначает не устройство а всего лишь авторизационную сессию.

- **Токены рассматриваются как дочерний ресурс аккаунта.**

  Например в эндпойнтах:
  `POST /accounts/{account_id}/tokens`
  `DELETE /accounts/{account_id}/tokens/{device_id}`
  `PUT /accounts/{account_id}/tokens/{device_id}/refresh`

   При этом `device_id` (он же `session_id` - см. первую проблему) в данном случае выглядит как дочерний ресурс, что является странным, т.к. не девайс создаётся в рамках существующих токенов, а токены создаются в рамках существующего девайса.

  Эту проблему можно решить (с учетом замены `device_id` -> `session_id`), если связать токены с авторизационной сессией и сделать токены дочерним ресурсом этой сессии.

  Т.е. станет:
  `POST /accounts/{account_id}/sessions`
  `POST /accounts/{account_id}/sessions/{session_id}/tokens`
  `DELETE /accounts/{account_id}/sessions/{session_id}`
  `DELETE /accounts/{account_id}/sessions`

  При этом мы изменили эндпойнт получения свежих токенов так, что теперь он выглядит как создание нового ресурса tokens в рамках конкретной сессии. Что также хорошо согласуется с семантикой REST архитектуры - описание действий (http методы), выполняемых над ресурсами (uri путь).

- **Эндпойнт логина требует `account_id`.**
  Это является технической проблемой апи, т.к. на момент запроса к эндпойнту логина, фронт не владеет информацией об аккаунте, и не может передать соответствующий `account_id`.

  Т.е. на данный момент эндпойнт выглядит следующим образом:
  `/accounts/{account_id}/tokens`

  Эту проблему можно решить (с учетом изменений описанных выше), если представить процедуру входа в систему, как создание новой авторизационной сессии.

  Т.е. эндпойнт будет выглдяеть так:
  `POST /sessions`

- **Эндпойнты принимают токены неконсистентно.**
  На данный момент access токен во всех эндпойнтах принимается через Authorization хедер, но при этом refresh токен, принимается через тело запроса. Эту проблему можно решить если создать отдельные fastapi dependency для валидации и парсинга каждого токена, например `get_access_token` и `get_refresh_token`. Обе они будут получать токен из хедера и возвращать пейлоад соответствующего токена.

- **Пейлоад токенов не зафиксирован в схемах.**
  При этом пейлоад токенов имеет важное значение с точки зрения безопасности. Можно зафиксировать схему пейлоада в виде типа возвращаемого значения из fastapi dependency, которая валидирует, парсит и проверяет токен. Планируемая схема пейлоада для токенов описана ниже.

**Пейлоад access-токена:**

- `account_id` - айди аккаунта пользователя, использующего access-токен.
   Позволит идентифицировать пользователя инициировавшего действие в системе.

- `session_id` - айди авторизационной сессии, с которой связан используемый access-токен.
  Позволит идентифицировать авторизационную сессию в рамках которой пользователь выполняет запрос, а также сделать access-токены уникальными, относительно разных сессий одного и того же пользователя.

- `created_at` - дата и время создания используемого access-токена.
  Позволит проверять expiration time для токена, а также сделать access-токены уникальными, относительно токенов, созданных в разное время в рамках одной и той же сессии - т.е. позволит сделать каждый новый "свежий" токен сессии уникальным.

**Пейлоад refresh-токена:**

- `session_id` - айди авторизационной сессии, с которой связан используемый refresh-токен.
  Позволит идентифицировать авторизационную сессию в рамках которой пользователь выполняет запрос, а также сделать refresh-токены уникальными, относительно разных сессий одно и того же пользователя.

- `created_at` - дата и время создания используемого refresh-токена.
  Позволит проверять expiration time для токена, а также сделать refresh-токены уникальными, относительно токенов, созданных в разное время в рамках одной и той же сессии - т.е. позволит сделать каждый новый "свежий" токен сессии уникальным.

В рамках этой задачи необходимо внести изменения в архитектуру эндпойнтов авторизации/аутентификации, исходя из правок, описанных выше.
birthdaysgift added a commit that referenced this issue Dec 12, 2023
Во время работы над добавлением сваггера для эндпойнтов авторизации (#77), была разработана архитектура авторизации/аутентификации, но как оказалось она содержит несколько недостатков:

- **Параметр `device_id` может вводить в заблуждение.**

  Например в эндпойнтах:
  `DELETE /accounts/{account_id}/tokens/{device_id}`
  `PUT /accounts/{account_id}/tokens/{device_id}/refresh`

  Потребителю апи может показаться, что `device_id` обозначает конкретный физический девайс, через который работает пользователь, но это не так, потому что даже в рамках одного физического устройства, пользователь может иметь несколько разных авторизационных сессий (например из разных браузеров).

  Для решения этой проблемы можно использовать название `session_id` вместо `device_id`. В данном случае, название `session_id` по смыслу подходит гораздо лучше, т.к. обозначает не устройство а всего лишь авторизационную сессию.

- **Токены рассматриваются как дочерний ресурс аккаунта.**

  Например в эндпойнтах:
  `POST /accounts/{account_id}/tokens`
  `DELETE /accounts/{account_id}/tokens/{device_id}`
  `PUT /accounts/{account_id}/tokens/{device_id}/refresh`

   При этом `device_id` (он же `session_id` - см. первую проблему) в данном случае выглядит как дочерний ресурс, что является странным, т.к. не девайс создаётся в рамках существующих токенов, а токены создаются в рамках существующего девайса.

  Эту проблему можно решить (с учетом замены `device_id` -> `session_id`), если связать токены с авторизационной сессией и сделать токены дочерним ресурсом этой сессии.

  Т.е. станет:
  `POST /accounts/{account_id}/sessions`
  `POST /accounts/{account_id}/sessions/{session_id}/tokens`
  `DELETE /accounts/{account_id}/sessions/{session_id}`
  `DELETE /accounts/{account_id}/sessions`

  При этом мы изменили эндпойнт получения свежих токенов так, что теперь он выглядит как создание нового ресурса tokens в рамках конкретной сессии. Что также хорошо согласуется с семантикой REST архитектуры - описание действий (http методы), выполняемых над ресурсами (uri путь).

- **Эндпойнт логина требует `account_id`.**
  Это является технической проблемой апи, т.к. на момент запроса к эндпойнту логина, фронт не владеет информацией об аккаунте, и не может передать соответствующий `account_id`.

  Т.е. на данный момент эндпойнт выглядит следующим образом:
  `/accounts/{account_id}/tokens`

  Эту проблему можно решить (с учетом изменений описанных выше), если представить процедуру входа в систему, как создание новой авторизационной сессии.

  Т.е. эндпойнт будет выглдяеть так:
  `POST /sessions`

- **Эндпойнты принимают токены неконсистентно.**
  На данный момент access токен во всех эндпойнтах принимается через Authorization хедер, но при этом refresh токен, принимается через тело запроса. Эту проблему можно решить если создать отдельные fastapi dependency для валидации и парсинга каждого токена, например `get_access_token` и `get_refresh_token`. Обе они будут получать токен из хедера и возвращать пейлоад соответствующего токена.

- **Пейлоад токенов не зафиксирован в схемах.**
  При этом пейлоад токенов имеет важное значение с точки зрения безопасности. Можно зафиксировать схему пейлоада в виде типа возвращаемого значения из fastapi dependency, которая валидирует, парсит и проверяет токен. Планируемая схема пейлоада для токенов описана ниже.

**Пейлоад access-токена:**

- `account_id` - айди аккаунта пользователя, использующего access-токен.
   Позволит идентифицировать пользователя инициировавшего действие в системе.

- `session_id` - айди авторизационной сессии, с которой связан используемый access-токен.
  Позволит идентифицировать авторизационную сессию в рамках которой пользователь выполняет запрос, а также сделать access-токены уникальными, относительно разных сессий одного и того же пользователя.

- `created_at` - дата и время создания используемого access-токена.
  Позволит проверять expiration time для токена, а также сделать access-токены уникальными, относительно токенов, созданных в разное время в рамках одной и той же сессии - т.е. позволит сделать каждый новый "свежий" токен сессии уникальным.

**Пейлоад refresh-токена:**

- `session_id` - айди авторизационной сессии, с которой связан используемый refresh-токен.
  Позволит идентифицировать авторизационную сессию в рамках которой пользователь выполняет запрос, а также сделать refresh-токены уникальными, относительно разных сессий одно и того же пользователя.

- `created_at` - дата и время создания используемого refresh-токена.
  Позволит проверять expiration time для токена, а также сделать refresh-токены уникальными, относительно токенов, созданных в разное время в рамках одной и той же сессии - т.е. позволит сделать каждый новый "свежий" токен сессии уникальным.

В рамках этой задачи необходимо внести изменения в архитектуру эндпойнтов авторизации/аутентификации, исходя из правок, описанных выше.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
1 participant