Flask & Vue. OAuth. Приклад№ 2.9


15.08.2021

У цій статті: OAuth в прикладах для Facebook, Google Account на Flask + Vue.

OAuth використовується для того, щоб ідентифікувати користувача сторонніми сервісами. Якщо Ви бачили на сайтах "Увійти через Facebook" - це воно.

Переваги і недоліки

Переваги:

  • Користувачеві простіше ідентифікуватися у Вашому додатку. Немає потреби вигадувати та запам'ятовувати логін / пароль.
  • Вам не потрібно перейматися збереженням логінів / паролів користувачів. Витік інформації і через це претензій до Вас менше.

Недоліки:

  • Якщо користувач втрачає доступ до свого акаунту Facebook / Google Account, він втрачає доступ і до Вашого додатку.
  • Якщо зловмисник отримає доступ до акаунту Facebook / Google Account користувача, він має потенційну можливість використати це для злочинних дій у Вашому додатку від імені користувача, який "профукав" свій акаунт.

Що ми будемо робити?

Ми додамо у попередній приклад функціонал, щоб користувачі могли потрапити в наш додаток:

  • класичним чином, вводячи логін/пароль
  • через Facebook та Google Account
  • роздача права (авторизація) буде виконуватися як і у попередньому прикладі

При цьому у додаток зможуть зайти тільки ті користувачі, яких ми вкажемо у таблиці користувачів. Права на доступ до різних даних будуть роздаватися, як і раніше. Нагадаю, у прикладі права прописуються у файлі access.json Для користувачів, які будуь проходить ідентифікацію через OAuth, у якості логіна будемо вказувати ідентифікатор. Для Facebook - це ім'я користувача у Facebook. Для Google Account - email користувача.

Як це працює в загалі?

  1. На своєму ресурсі Ви робите спеціальне посилання для входу через Facebook / Google Account, тощо. Як саме зробити це посилання згодом розповім.
  2. Користувач переходить за посиланням, і якщо потрібно, вводить логін/пароль до свого акаунту Facebook або Google Account в залежності від того через що він наважився ідентифікуватися.
  3. У випадку вдалого входу Facebook або Google Account перенаправляє браузер користувача на сторінку нашого ресурсу з кодом для перевірки.
  4. Бекенд, отримавши код перевіряє його у Facebook або Google Account і якщо отримає підтвердження валідності коду, може отримати ідентифікаційні дані користувача. Ми будемо ідентифікувати користувача за ім'ям у Facebook, та за e-mail у Google Account.

Отримавши данні про користувача ідентифікація вважається вдалою.

Що треба зробити щоб організувати вхід через Facebook або Google Account у своєму додатку?

Звісно, щоб це організувати треба якось налаштувати Facebook та Google Account, щоб він знав, що це саме з нашого ресурсу намагаються ідентифікуватися і вказати куди потім перенаправляти користувача у разі вдалої ідентифікації. Для цього треба:

Facebook

1. Йдемо сюди: https://developers.facebook.com/apps/

Жмем "Создать приложение".

Обираємо потрібне:

Закінчуємо створення:

Запитає пароль для підтвердження:

Видасть таке:

2. Жмем «Вход через Facebook → Настроить» Відкриється майстер налаштувань. Пропустіть його - віразу переходьте у розділ «Продукты → Вход через Facebook → Настройки».

Вмикаємо "Клиентская авторизация OAuth", Вказуємо "Действительные URI перенаправления для OAuth"

3. Переходимо у розділ «Настройки → Основное» и скопіюйте «Идентификатор приложения» та «Секрет приложения».

Нас цікавить:

"ID приложения": 914******730949
"Секрет приложения": 9a2e2aafe6a*********b7f0cc017

Google Account

1. Йдемо сюди: https://console.developers.google.com/cloud-resource-manager

Створюємо проєкт: MyTestProject

2. Йдем в меню: OAuth consent screen. Налаштовуємо там все

3. Йдем в Credentials Створюємо OAuth 2.0 Client IDs

Нас цікавить Client ID, Client secret

Приклад:

334426459531-dvguu**********hdptq9se0pu.apps.googleusercontent.com
WwtMkGuY*******IetOzah

Складнощі, що виникали під час реалізації прикладу

1. Після вдалої аутентифікації, Facebook та Google Account викликають перенаправлення на сторінку ресурсу з додаванням у кінець кода типу такого: ?code=AAAAAAAA Теоретично, ми могли вказати сторінку https://domain/frontend/#/login, тоді користувач потрапляв би на сторінку з таким посиланням: https://domain/frontend/#/login?code=AAAAAAAA

Та от біда! Від символу "?" після символу "#" фронтенду "рве кришу". Тому нам доведеться викликати посилання на бекенд. В інших випадках - це норм. Але в нас така реалізація, що після аутентифікації фронт має отримати токен і тому логічно було б щоб саме з фронту на бек летів цей код для перевірки. Тому, у моєму прикладі, бекенд отримавши код від Facebook/Google Account, редіректить користувача на фронтенд і тоді вже фронт передає беку код для остаточної перевірки. І якщо все ОК, тоді ВЕЛКАМ, а як ні - то користувач отримує повідомлення і залишається у формі логіну.

2. OAuth вимагає, щоб Ваш ресурс обов'язково був https://...!

Що робити, якщо ми хочемо погратися, на http://localhost:5000/?. Або додаток буде працювати в нашій локальній (корпоративній) мережі і зі сторони інтернету на нього не попасти? Правильно - в налаштуваннях OAuth будемо вказувати посилання на сторінку нашого ресурсу з https (Наприклад, у мене це https://blog.avislab.com/oauth/fb/login/, https://blog.avislab.com/oauth/ga/login/), а на ньому зробимо "редірект" на http://localhost:5000/ за допомогою JavaScript.

Код JS скрипта такий:

  window.location.href = window.location.href.replace('https://blog.avislab.com/','http://localhost:5000/').replace('/?','?')

Таким чином, зможемо тестувати OAuth на будь якому локальному компі.

Схема, як браузер користувача "біга" туди-сюди зображена на малюнку:

Ще раз докладніше

Оскільки для формування посилання для входу через Facebook, Google Account (а потім і для перевірки) треба використовувати ідентифікатори і іншу інформацію від Facebook та Google, я не додавав її у фронтенд, а тільки на бекенд. Фронт не знає за яким посиланням заходити на Facebook чи Google Account. До того ж посилання може змінитися і щоб не коригувати данні у двох місцях, я зробив на бекенді два роути які формують посилання і редиректат користувача на Facebook або Google Account для входу:

http://localhost:5000/oauth/login/ga
http://localhost:5000/oauth/login/fb
На фроні ці посилання статичні, і якщо щось зміниться, поправляти доведеться тільки на бекенді. Дивись файл config.py

Далі, коли користувач потрапив для аутентифікації на Facebook, Google Account, він якщо треба, вводить пароль, обирає акаунт, тощо. Якщо він все зробив як слід, браузер користувача редиректиться на https://blog.avislab.com/oauth/fb/login/, коли входив через Facebook, або https://blog.avislab.com/oauth/ga/login/, коли входив через Google Account.

З цих сторінок за допомогою JS відбувається перенаправлення на http://localhost:5000/. (Ми не можемо вказати http://localhost:5000/ у налаштуваннях Facebook, Google Account. Ресурс обов’язково має бути HTTPS).

Код перевірки отримує бекенд, але не перевіряє його відразу, а "загортає" і перенаправляє браузер користувача на фронтенд. Це зроблено для того, щоб саме зі сторони нашого фронтенда на бекенд прилетів запит з кодом на перевірку, і фронтенд мав змогу отримати токен для подальшої роботи.

Фронтенд "розгортає" отриманий код і відправляє на бекенд для перевірки.

Тут "пін-понг" закінчується і Бекенд нарешті перевіряє код і якщо все гуд - перевіряє чи є користувач з таким ідентифікатором у власній таблиці користувачів, якщо є - тоді генерує і відає фронту токен. Такий самий токен, як і при вході звичайного користувача. Звісно таблиця користувачів була модифікована, щоб можна було вказувати через яку систему буде потрапляти користувач. А права на доступ, як і раніше, прописуються у файлі access.json.

Таким чином, можна організувати вхід у додаток декількома шляхами. OAuth - це один з них. Також у прикладі наведено метод, завдяки якому можна організувати вхід у додаток через OAuth, навіть, коли він знаходиться у локальній мережі чи навіть на локальному компі.

Як зібрати і запустити приклад?

Зкачати приклад за цим посиланням, встановити все, чого не вистачає власноруч.

Або скачати архів з усім барахлом, розпакувати і вперед.

Дивись також:

web-dev склерозник
Коментарі:

Додати коментар

* - обов'язкові поля

Архіви