0: Итак, давайте продолжим здесь сейчас мы принимаем каким-то образом токен очень непонятным просто аргументом токен давайте сошлёмся в функции get current user на функцию get token поймём, как это делается именно в фастапи.
1: Здесь мы посмотрим на зависимости. Именно поэтому файлик и называется депенденсис, потому что мы будем использовать такую функцию под названием депендс. Итак, токен у нас имеет тип стр. Не забываем это писать и пишем, что он зависит.
2: От вот этой функции депен импортируем из фастапи. И что здесь вообще происходит? Что такое депен. То есть можно подумать, что мы бы могли токен условно вот таким образом добыть.
3: И потом как-то его сюда, например, передать. Но на самом деле нет в фастапи реквест. То есть запрос пользовательский существует только в рамках какого-либо эндпоинта, то есть всегда вот
4: Эта функция с реквестом, если она используется в другой функции, мы всегда должны потом дойти на самый верхний уровень, до эндпоинта. Ой, ой, ой, тут какой-то спойлер, и здесь также будет использоваться депендс. У нас будет user какого?
5: Типа users, который мы в sq алхимии задавали, и он будет также зависеть от функции get current user, которая находится вот здесь, конечно, её тоже нужно импортировать таким.
6: Образом, мы не можем отдельно где-то вызвать вот эту функцию get current user, потому что она существует только для конкретного запроса, соответственно, user перед тем, как запустится эндпоинт, вообще любой код будет исполняться у нас.
7: Если есть депен, запустится функция внутри депен. То есть, по сути, фастапи вызовет эту функцию. Окей, он вызывает эту функцию, давайте на неё провалимся, что происходит дальше? Здесь опять есть в аргументах зависимость какая-то депен. И здесь код тоже не прогоняется.
8: Пока что мы спускаемся ещё ниже в get token здесь уже нет никаких депендс, здесь уже есть request, и мы из него что-то добываем, да, вот, например вот этот токен, вот эту куку, если её нет, возвращаем ошибку и ошибка поднимется вот сюда выше.
9: Выше, выше и отдастся пользователю ошибка. И вообще никакой код не будет исполнен ни здесь, ни вот здесь. Иначе, если все хорошо, мы можем с этим токеном работать и его раскодировать. Давайте этим сегодня сейчас займёмся. Есть
10: 4 шага. Давайте сначала посмотрим перед этими шагами на сайт джт ио. Уже знакомый нам, я сюда вставил.
11: Куку. Я просто скопировал её через правой кнопкой мыши посмотреть код и зашёл в консоль разработчика, как она сейчас выглядит. Просто, чтобы мы понимали, нам не особо важно, что в заголовке, что в подписи нам важно, что в пайлоу, то есть в данных есть
12: Айдишник пользователя и есть время экспирации, да, вот, собственно, таймстемп количество секунд от 1 января 70 года. Что нам нужно сделать при работе с джт токеном? Во первых, проверить, что это
13: Токен. Вдруг у нас в куках содержится вот что-нибудь такое. Это не джт токен. Когда мы убедимся, что это джт токен, мы хотим посмотреть, что экспирация ещё не прошла, что токен действителен, он может использоваться для Логина пароля.
14: Для того, чтобы работать с пользователем, отдавать ему данные дальше. Если все окей, мы смотрим, что есть параметр, ключ саб с id пользователя, если его нет, возвращаем ошибку. Если он есть, мы возвращаем, мы делаем запрос в базу.
15: Данных. И смотрим, есть ли пользователь с таким айдишником. И если он есть, только тогда мы возвращаем этого пользователя, то есть нужно пройти много, много ступенек, чтобы убедиться, что jivo этот токен, с ним все хорошо, он не истёк, он валиден, что там есть необходи
16: Поля и только потом мы вернём пользователя. Итак, давайте перейдём в visual studio code и попробуем написать за 1 урок весь этот код. 1 давайте импортируем из библиотеки с таким названием джива.
17: И сразу импортируем жвт эрр, потому что у нас может быть ошибка с этим токеном, когда мы будем проверять, что это действительно джв токен. Соответственно, мы напишем конструкцию трай эксепт. Здесь будет эксепт именно жвт эр, если она
18: Случится. Если она случится, то мы вернём просто ошибку с 401 кодом. 401 код. Давайте вспомним, чтобы лучше было используем статус из фастапи. Статус вот здесь. Ой, ой, ой, статус, точка, http.
19: 401 и вот так будем использовать, чтобы было нам понятнее, лучше запоминалось то, что пользователь не аутентифицирован, мы возвращаем ему ошибку. Так вот как, собственно проверить, что jit токен то настоящий мы использовали раньше.
20: Функцию энкод для кодирования, а сейчас будем декод для декодирования. Итак, давайте напишем здесь пэйлот, то есть нам нужны именно вот эти данные, нам не интересны хедеры и подпись. Вот так.
21: Сделаем таб и здесь вместо энкод просто укажем декод, сеттинги, сеттингс мы импортируем из app config, нам почему-то советуют сеттинг с большой буквы импортировать, но мы немножко тут поменяем конечно с маленькой, потому что переменная с большой буквы это класс и здесь вместо.
22: Туэн код, у нас есть токен, который мы декодируем. Если все хорошо пройдёт, то эта ошибка не отработает, и мы дальше можем работать с пэйлот, и мы можем достать время экспирации. Экспайр. Это строка, кстати.
23: Сейчас получим. Да, давайте эксп. Хочу обратить ваше внимание, что была допущена мною ошибка, когда мы кодировали токен в эндпоинте. Логин. Мы вот здесь, у нас было просто user id без строки, и это
24: Ошибка. Необходимо приводить каждый раз значение ключа любого в токене к строке то привели к строке, и ругаться он уже не будет. Итак, мы получили экспайр.
25: И давайте, во первых, проверим, что он есть и expire и сравним его с текущим временем, то есть если экспайр меньше, чем текущее время, то есть он истёк, тогда отдадим ошибку итак, у нас
26: Если, например, нет экспайра, да, вот так лучше сделаем. Если нет экспайра или он истёк, тогда мы отдадим ошибку. Давайте сразу ошибочку напишем. И, конечно, здесь я забыл слово рейс, чтобы ошибку вернуть. Рейс.
27: И давайте проверим во первых у нас экспайр это строка, поэтому нужно привести её к интеджеру если int экспайр меньше чем текущее время, текущее время у нас как давайте даже немножко стырим кодика здесь мы уже писали.
28: Текущее время в аут вот оно, текущее время дейт тайм точка ютиси нау. Если оно меньше чем day time utc нау. Причём дейттайм нужно импортировать из date time вот таким образом тогда.
29: Мы вернём ошибку, если у нас есть экспайр и у нас он валидный, ещё время не прошло, тогда все окей. Идём дальше. Следующий этап, который у нас был, это получение. User id, давайте здесь напишем. User id, это у нас саб.
30: И опять же, если нету. User id, тогда верни ошибку, и мы уже, смотрите, в который раз копируем 1 и ту же ошибку у нас уже 4 раза в коде встречается то, что пользователь не аутентифицирован.
31: Какие проблемы в связи с этим встают? Ну, во первых, если у нас выйдет 401 ошибка, мы не знаем, из за чего она вышла, у нас нет никаких деталей. Да, вот есть на самом деле аргумент детейл, детейл, и в нём можно указывать, что на самом деле произошло вот здесь.
32: Например, там токен не является. Джив, например, можно написать, и пользователь при получении 401 ошибки сможет понять, что ему дальше делать, чтобы все хорошо прошло, потому что иначе для него наш апи, это чёрный ящик и
33: Также, конечно, у нас повторение кода идёт где-то, может быть одинаковые ошибки выдаваться с одинаковым дитейл с одинаковым описанием и, конечно, хорошо их будет вынести в отдельный файл со всеми исключениями, что мы, собственно, и сделаем. Итак,
34: После того, как мы забрали user id, мы убедились, что окей, он есть, теперь нам нужно забрать пользователя, вспомним в пользователе есть дао, который наследуется от base дао, и у нас есть метод find by id, и как раз по айдишнику мы сможем найти
35: И нам вернётся либо пользователь, либо ничего, никого не вернётся, либо none. И что очень важно, у нас эта функция асинхронная. Поэтому здесь тоже нам придётся функцию сделать асинхронной. Так как нам нужно использовать await. Давайте.
36: К users дао, обратимся, его импортируем файнд бай айди нам подсказывают и айдишник будет user id таким образом, нам вернётся здесь либо none, либо user, if not user, то есть есл.
37: Пользователь не вернулся. Давайте опять вернём ту же самую ошибку уже в какой раз. Если же с ним все хорошо, то здесь вот эту строчку мы наконец можем сменить на юзер, и мы возвращаем на самом деле модель пользователя здесь
38: Мы её принимаем, да, поэтому она является моделью Эске алхимии, и мы сможем здесь с ней работать таким образом, например, ну, давайте запринти юзер тайп юзер, чтобы посмотреть, какого он типа и сразу я
39: User, например, id. Чтобы убедиться, что действительно мы можем работать с какими-то его параметрами, ну, например, с емейлом, пускай возвращать пока ничего не будем. Окей, сохранили, здесь тоже сохранили, вроде выглядит все.
40: Нормально. И давайте попробуем посмотреть, как у нас все работает в документации. Очень важно, конечно, чтобы токен был свежий, чтобы ошибки не было. Давайте ещё раз напишем.
41: Получим свежий токен. Вот он, соответственно, эксперация у нас ещё через 30 минут только так и здесь нам требуют токен. Почему же так? Давайте посмотрим. Так, я обновил страничку. Все пропало как обычно. Итак.
42: Tried out execute и мы не авторизованы. Ошибка 401. И вот здесь Гадай что пошло не так, ведь непонятно и приходится тогда такое дело каким-то образом дебажить смотреть где произошла ошибка. Если бы
43: У нас была, были хорошо настроенные детали, хорошо настроенные описания. Мы бы сразу поняли, где ошибка, и исправили её со стороны клиента. Я имею ввиду, когда вот мы как клиент пользуемся. Ну и, конечно, это не очень приятно, когда также непоня
44: Понятно. И разработчикам, что за ошибка произошла. Давайте разбираться. Итак, 1 ошибка, которая часто, конечно, встречается, это просто забыл какую-то букву. Давайте здесь напишем букинг эксесс и посмотрим ещё раз, все ли у нас вообще хорошо.
45: И теперь у нас уже какая-то другая ошибка. Посмотрим что происходит. Да, действительно, я забыл привести к типам. У нас же day time utc нау немножко другой тип отдаёт точка дей тайм. Нам нужно его привести к таймстемпу и
46: Уже тип float. Соответственно, мы можем сравнить инт и флот сохраняем, делаем заново экзекьют, опять исправляем ошибочку и смотрим, что здесь не так. А мы передаём неверный тип. Давайте.
47: Делаем тогда так, что мы здесь приведём к интеджеру. Наш user id.
48: И давайте попробуем в 3 раз. И сейчас у нас ничего не возвращается. Но в консоль вывелось то, что мы и хотели. У нас вывелась, во первых, почта пользователя, то есть вуаля, ура, можно радоваться, мы получили данные пользователя.
49: Из его cookie вот такими хитрыми действиями. Дальше мы поняли, что это действительно класс эскью химии. Мы можем с ним работать, как и как обычно, можем к нему обращаться через юзер точка емейл юзер точка айди вообще.
50: Те параметры из него доставать, которые только в нём есть, вот эти
51: И что ещё? Давайте, например, выведем его на печать, посмотрим, что вообще там творится.
52: И мы увидим емейл айди и хэш паспорт. И на самом деле, возможно, стоит сделать для юзеров, для юзерс дао отдельный метод, который будет возвращать только емейл и id без хэшированного пароля, потому что, ну вдруг кто-то из
53: Разработчиков где-то вот случайно вернёт юзер. И мы точно не хотим, чтобы хэшированный пароль возвращался или, например, емейл возвращался. То есть можно вот здесь использовать не find by id, который возвращает все поля таблицы. А
54: Для юзеров сделать свой какой-то конкретный, отдельный метод, который бы возвращал только айдишник и, например, там возраст, любимый цвет. Ну, какие-то не очень чувствительные данные. Об этом тоже всегда нужно помнить, потому что разные разработчики бывают, если в common
55: Много людей, то кто-нибудь может ошибиться. И давайте наконец то уже устали, но тем не менее заберём букинги все конкретного пользователя.
56: Давайте здесь букинги, посмотрим, что у нас есть find, и нам нужны условия, конечно же, find one or find all по условию давайте сделаем, чтобы юзер айди равен.
57: Был user.
58: Id, то есть здесь мы наконец то сможем отдать там, например, шарику букинги, шарика, матроскину букинги матроскина. Эх, но так получается, что для теста, вот для этого пользователя, где
59: Для тест собака тест. Мы забыли сделать какие-либо букинги, поэтому нам вернулся пустой список. Конечно, грустно, что не получили какой-то результат, но тем не менее, мы знаем, что если мы добавим какой-либо букинг на этого пользователя, мы уже его получим, да, например, здесь
60: Давайте сделаем 1 пользователя у нас 1, ну просто чтобы проверить, что, ну, вдруг шарик зашёл на наш сайт или кто там у нас 1 i захотел посмотреть свои букинги, да, ему вернулись бы все букинги, он был бы доволен.
61: Болен, а пока что у нашего пользователя не