Руководство Django Часть 8: Аутентификация и авторизация пользователя – Изучение веб-разработки | MDN

Почему oauth, а не виджет «войти через»?

Нет проблем. Если вас устраивают функционал, дизайн и уровень безопасности виджета — то его воткнуть в код на самом деле намного проще — можете дальше не читать.

Вводная часть

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

Почему oauth, а не openid?

Потому что OpenID практически бесполезен для тех целей, для которых декларирован. Это сугубо мое мнение, но оно опирается не на пустое место.

Во-первых, OpenID пользуются в основном «гики», процент которых в интернете не настолько высок, чтобы перестраивать под них сайты (за некоторым исключением, разумеется 🙂 ) Почему так? Потому что для того, чтобы получить OpenID аккаунт, надо — его получить.

Зайти на OpenID сервер и предпринять некоторые действия, чтобы заполучить некий, довольно невразумительный, набор символов. Который, несмотря на сложность (для простого пользователя) надо не забыть и вводить при случае, если на глаза попадется знакомая пиктограмма

image

. Ну какой казуальный пользователь будет это делать? А с OAuth все намного проще — видит человек кнопку «Войти через ВКонтакте», нажимает, и… уже на сайте с правами зарегистрированного пользователя. «Будьте проще», — говорил классик, — «и люди к вам потянутся». Как в воду глядел.

Во-вторых, возможности OAuth далеко не исчерпываются аутентификацией и авторизацией. Получив в процессе авторизации токен, его можно использовать для дальнейшей интеграции возможностей социалки в свой ресурс — чтение/написание постов, доступ к френдленте и стене и многое другое.

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

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

Кроме того, OpenID аутентификация, в сущности, не дает никаких гарантий клиенту. Она подтверждает лишь, что запрашиваемый пользователь действительно зарегистрирован на одном из OpenID-серверов — и все. Механизмы получения дополнительной информации о пользователе (email, имя, возраст) имеются, но мало кем поддерживаются.

Можно, конечно, в нарушение идей OpenID, анализировать идентификатор и доверять только определенным OpenID-провайдерам (например, тем же социалкам). Но смысл, если почти все из них (за исключением ЖЖ, но он и по OpenID ровным счетом ничего не расскажет о пользователе)

Api: сервер ресурсов

Сервер ресурсов это API сервер используемый для получения доступа к информации пользователя.

Client id, secret

После регистрации приложения, будут получены идентификатор клиента Client ID (UID) и секрет (secret). Client ID это публичный информация, и используется открыто для формирования URL, или включения в JavaScript-код приложения на странице. Secret должен сохраняться в тайне и не передаваться в публичный доступ.

Google

1. Идем

. Создаем новый проект. На вкладке API access нажимаем кнопку «Create an OAuth2 client ID».

image

Получаем client_id(Client ID) и secret_key(Client Secret).

image

2. Код кнопки должен быть вида:

Oauth = fetch request token redirect to authorization fetch access token call api

В примере с GMail мы использовали 2 вида удаленных вызовов: а) редирект через браузер; б) обращение к API изнутри скрипта.

И мы вскрыли ряд проблем с безопасностью, что наводит на мысль: вызовов должно быть больше. Так и происходит в OAuth: добавляются еще промежуточные запросы от скрипта Consumer-а к Provider-у, оперирующие токенами. Давайте их рассмотрим.

Oauth для полностью клиентских приложений

Стороннее приложение может представлять собой лишь графический интерфейс без серверной бизнес-логики и выполнять взаимодействие с сервисом API с помощью кода на клиенте — например, мобильное приложение календаря, заметок и т.д.

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

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

При таком подходе опускается обмен кода авторизации на токен доступа во время обмена запросами между серверами приложения и API. Вся авторизация, как было отмечено ранее, происходит на стороне клиента.

Web server apps

Серверные веб-приложения основной тип приложений для работы с OAuth. Приложения написаны на серверных языках и выполняются на сервере, где исходный код не доступен публично. Что значит приложение может использовать Client Secret для коммуникации с сервером авторизации.

Авторизация

Создать случайную строку длиной 43-128 символов, затем сгенерировать url-безопасный base64 SHA256 хеш на основе этой строки. Оригинальная строка будет называться code_verifier, в хеш версия code_challenge

Например, строка, code_verifier

5d2309e5bb73b864f989753887fe52f79ce5270395e25862da6940d5

Hash, SHA256, base64-encoded, code_challenge

MChCW5vD-3h03HMGFZYskOSTir7II_MMTb8a9rJNhnI

Строка входа будет такой

Блок 1 настройки серверов авторизации

service_config={"google":{'code':"",'url_token':"https://accounts.google.com/o/oauth2/token",'url_user_info':"https://www.googleapis.com/oauth2/v1/userinfo",'client_id':"....",'client_secret':"...",'redirect_uri':"http://...",'grant_type':'authorization_code'},"yandex":{'code':'','url_token':'https://oauth.yandex.ru/token','url_user_info':'https://login.yandex.ru/info','grant_type':'authorization_code','client_id':'...','client_secret':"..."},"facebook":{'code':'','url_token':'https://graph.facebook.com/oauth/access_token','url_user_info':'https://graph.facebook.com/me','client_id':'...','client_secret':'...','redirect_uri':"http://..."},"vkontakte":{'code':'','url_token':'https://oauth.vk.com/access_token','url_user_info':'https://api.vk.com/method/users.get?fields=uid,first_name,last_name,nickname,screen_name,sex,bdate,city,country,timezone,photo','client_id':'...','client_secret':'...','redirect_uri':"http://..."}}

Для настройки ОАuth авторизации через другой сервер (не приведенный в листинге) – просто добавить соотвествующие настройки

Блок 3 приведение данных о пользователе к единой форме

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

  1. создаем для каждого сервера авторизации необходимую функцию, обрабатывающую переданную информацию о пользователе. В качестве обязательных параметров функции передаются:
    • param_token – ответ сервера авторизации с access_token (см. выше шаг 2). VKontakte передает адрес почты пользователя в access_token
    • param_info – собственно данные о пользователе,

Вот пример функций для рассматриваемых серверов авторизации

  1. Связываем каждую функцию со значением параметра state (см. выше)
  1. В основной функции (блок 2) добавляем строку

Теперь информация о пользователе возвращается в структурированном виде.

Вконтакте

1. Идем

. Тип — «Веб-сайт». Вводим базовый домен и адрес сайта. На странице настроек получаем client_id (ID приложения) и secret_key (защищенный ключ).

image

2. Втыкаем в код кнопку вида

Грабли вторые: «подслушивание» секретного ключа


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

Secret можно подсмотреть из-за спины или перехватить методом прослушивания WiFi-трафика. Или на вашем сайте когда-нибудь найдется XSS-уязвимость, позволяющая «утянуть» секретный ключ. Имея значение secret, злоумышленник сможет прочитать вашу адресную книгу. Значит, нужно обезопасить secret от перехвата (в идеале — вообще его не передавать через URL).

Грабли первые: подмена адреса возврата retpath

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

и заставит вас на нее кликнуть. В результате он получит секретный ключ, который вернул GMail, а значит, и ваши контакты:

Грабли третьи: слишком много редиректов


Если для каждого вызова API требуется разный secret, то нам придется организовывать столько редиректов на сайт Service Provider-а, сколько у нас вызовов. При интенсивном использовании API это работает очень медленно, да и неудобно порядком…

Грабли четвертые: плохая идентификация consumer-а

GMail, конечно, хочет знать, кто пользуется его API. Разрешить доступ одним сайтам и запретить — другим… Значит, при формировании запроса в форме импорта контактов Consumer (сайт) должен «представляться» Service Provider-у (GMail-у). В нашем случае эту функцию частично выполняет retpath (имя сайта в нем), но данный способ не универсален, т.к. механизм «представления» должен быть задейстсован еще и при вызове API-методов.

Демонстрация работы oauth на примере простого приложения

Чтобы «вживую пощупать» OAuth, нам потребуются две вещи:

Доступ приложений

В некоторых случаях, приложениям нужен  токен доступа для работы от своего имени, а не от имени пользователя. Например для сбора статистики или обновления своих настроек. Для подобных случаев используется поток client_credentials

Заглянем под капот oauth

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

Запросы

После получения токена можно выполнять запросы к защищенным данным

Используемые роли в oauth 2

В рамках описываемого протокола выделяются следующие типы ролей:

  • владелец (пользователь): авторизует клиентское приложение на доступ к данным своего аккаунта;
  • сервер ресурсов/API: здесь располагаются данные пользовательских аккаунтов, а также бизнес-логика авторизации, отвечающая за выдачу новых OAuth-токенов и проверку их подлинности при обращении клиентских приложений к ресурсам. Целесообразно объединять эти роли, так как физически это один сервис;
  • клиентское приложение: собственно сервис, которому пользователь делегирует права доступа к своим данным на сервере ресурсов. Пользователь должен авторизовать приложение, а со стороны сервера API оно должно получить подтверждение в виде ключа (токена) доступа. 

Как это работает.

Если кому интересны все подробности, то см. ссылки выше. А вкратце — так:

Минусы

  • различия в подходах к реализации у разных сервисов, порождающие необходимость написания отдельного кода под каждый новый сервис;
  • если реализована интеграция с семейством приложений, работающих в одной экосистеме (например, Google), существует риск для всех интеграций при компрометации учетных данных либо сбое на стороне сервера API;
  • OAuth 2.0 является новым и динамично развивающимся протоколом, в связи с чем возможны некоторые логические противоречия в его спецификации;
  • основанная на SSL безопасность протокола может стать проблемой в высоконагруженных проектах.

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

Если 15 лет назад для того, чтобы называть себя фронтенд-разработчиком достаточно было знать HTML, CSS и JavaScript, то сейчас фронтенд-разработка почти не отстает от бэкенд-разработки по количеству фреймворков и сложности стеков. Самый быстрый и качественный вариант — получить знания из первых рук от преподавателей со стажем. Поэтому мы запустили курс «Frontend Basic: принцип работы современного веба», на котором вы:

  • освоите стек технологий, который позволит начать работать в любой компании на любом проекте;
  • сверстаете свой первый адаптивный макет с учетом семантики и множества декоративных элементов на HTML и CSS;
  • поймете, как с помощью JavaScript разрабатывать пользовательские интерфейсы;
  • разберетесь, как JavaScript используется в работе с backend и создадите свой первый обмен данными сервером;
  • углубитесь в более сложную разработку на React.js и напишете свой интернет-магазин;
  • изучите основные команды для работы с GIT, важнейшего инструмента для работы в любой команде.

Мобильные приложения

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

Об изобретении велосипедов

Хороший способ понять что-то — сделать это самому, наступив попутно на все разложенные грабли. Сейчас мы будем изобретать велосипед: попробуем представить, как бы мы решали задачу взаимодействия Consumer-а и Service Provider-а без всяких стандартизированных протоколов.

Во-первых, напишем саму форму импорта контактов с GMail:

Далее попросим разработчиков GMail сделать так, чтобы при переходе пользователя по URI /auth.php ему бы выдавалась форма авторизации (в нашем веломире GMail написан на PHP). После успешного ввода пароля пользователь должен редиректиться на сайт, чей URL указан в параметре retpath.

Итак, после ввода пароля пользователь будет возвращаться к нам на сайт по следующему адресу:

А мы из скрипта /import.php обратимся к API GMail, передадим в него ключ Y49xdN0Zo2B5v0RR и загрузим контакты:

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

Области и токены oauth

Области и токены OAuth реализуют детализированное управление доступом. Похоже на киносеанс: область – название фильма, который вы имеете право смотреть, токен – билет, что может проверить лишь сотрудник конкретного кинотеатра.

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

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

Условно можно выделить
четыре типа областей:

  • доступ для чтения;
  • доступ на запись;
  • доступ для чтения и записи;
  • без доступа.

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

Обновление доступа

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

Одноклассники

1. Регистрируемся как разработчик

. Идем

и заполняем заявку на получение OAuth доступа. Н-да. Заявка, похоже, обрабатывается вручную. Если ответа в течение суток нет, пинаем поддержку по тому же адресу. «Одноклассники», что тут скажешь…

2. Получаем письмо с инструкциями и, следуя им, заполняем форму.

image


Все заполненные в примере поля обязательны к заполнению. Нажимаем «Сохранить» и получаем письмо на указанный емайл, содержащее client_id(Application ID), public_key(Публичный ключ приложения) и secret_key(Секретный ключ приложения)

3. Код кнопки должен быть вида:

Переход с сайта на страницу авторизации

Как правило, для перехода на страницу сервера авторизации на сайт вешается кнопка, например, так:

В качестве значения ссылки указываем адрес сервера авторизации с набором параметров
Адреса на страницы авторизации

При переходе по указанным ссылкам необходимо передать следующие параметры:

  • response_type=code – (code – значение параметра для нашего случая авторизации)
  • client_id – значение присвоенное сервером авторизации при регистрации сайта
  • redirect_uri – URI адрес нашего серверного скрипта, которому будет передано управление после ввода пользователем пароля на сервере авторизации. Управление передается посредством отправки сервером скрипту GET запроса.
  • state – не обязательный, но полезный параметр. В него помещается произвольное значение. После успешной авторизации пользователем это же значение возвращается серверному скрипту в GET запросе. Например, в качестве значения этого параметра можно указать псевдоним сервера авторизации Это же значение сервер авторизации направит серверному скрипту. Таким образом, скрипт сможет идентифицировать с какого сервера авторизации пришел запрос.
  • scope указывает серверу авторизации какие дополнительные данные пользователя мы запрашиваем для нашего сайта. Пользователь при прохождении авторизации увидит какие его данные хочет получить наш сайт, соглашается с этим или отклоняет авторизацию. Обязательные данные при прохождении автризации будут возвращаться нашему сайту всегда. К обязательным данным прежде всего относится id пользователя на сервере авторизации

Из дополнительных параметров о пользователе, скорее всего, понадобится его email. поэтому в параметре scope нужно указать

Параметры для доступа к другим дополнительным параметрам пользователя можно посмотреть здесь

План этой статьи

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

  1. Рассмотрим проблемы, которые возникают при «ручной» реализации кросс-авторизации.
  2. Поговорим о том, что такое «приложение» и кто такой Consumer.
  3. Коснемся основ криптографии.
  4. Обозначим демо-приложение, которое мы будем писать в этой статье.
  5. Определимся с тестовым сервером OAuth, на котором будем экспериментировать.
  6. Пройдем по всем шагам протокола OAuth и приведем исходники скрипта.

Плюсы

  • использование SSL для защиты данных,
  • ограничение прав доступа стороннего приложения к пользовательским ресурсам областями видимости,
  • обилие библиотек для реализации использования протокола во всех языках общего назначения.

Полезные ссылки по oauth

См. также:

Получение токена доступа

Для получения токена отправляем POST запрос, указывая полученный код авторизации

Пользователь, владелец ресурса

Владелец ресурса это реальный пользователь, который выдает доступ к части своей информации.

Практические рекомендации по реализации

Разумеется, в первую очередь надо зарегистрироваться в соцсети, активировать аккаунт, ну и всё такое. Не торопиться. Некоторые сервера не сразу корректно обрабатывают запросы от свежезарегистрированных OAuth-клиентов. Здесь я расписал только успешные потоки, забывать про обработку ошибок — никак не стоит.

Также я практически не уделил внимания аспектам безопасности — это тема отдельной статьи. Как минимум, везде, где можно передавать уникальный параметр в callback-url для каждого пользователя — это стоит делать (Основной callback адрес должен оставаться без изменений, а меняться — только параметр, иначе сервер не пропустит запрос.

Преимущества и недостатки oauth 2

Рассмотрим подробнее плюсы и минусы протокола авторизации.

Приложение = consumer доступ к api

При работе с OAuth важно, что термин Consumer не ограничивается смыслом «сайт». Consumer — это некоторое

приложение

, а уж где оно размещено, не так важно. Примеры Consumer-ов из реальной жизни:

Но из одного OAuth каши не сваришь. Действительно, все, что дает OAuth, — это возможность авторизоваться на удаленном сервисе (Service Provider) и делать автризованные запросы к API. Не важно, как устроен этот API: это может быть чистый SOAP, REST-подход т. д. Главное, чтобы каждый метод API принимал на вход специальные параметры, передаваемые согласно протоколу OAuth.

Пример реализации протокола на php

Рассмотрим живой пример проекта клиент-серверного стороннего приложения, взаимодействующего по API с сервисом Google Таблицы.

Пример: github sso

Изучим описанные
концепции на примере. Teleport – опенсорсный
инструмент удаленного доступа, позволяющий юзерам входить в систему через
Github single sign-on (SSO) с использованием OAuth. Действующиелица:

Рис. 4. Поток разрешения авторизации
Рис. 4. Поток разрешения авторизации

Рассмотрим поток шаг за шагом.

Шаг 1. Пользователь Teleport получает доступ к приложению Teleport.

Шаг 2. Приложение предлагает пользователю Teleport войти с помощью Github SSO.

Различия протоколов openid и oauth 2

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

Для верификации пользователя OpenID использует ID учетной записи у провайдера, а OAuth — авторизационные ключи (токены) с предопределенным сроком действия и правами доступа.

Разрешения и потоки oauth

Возвращаясь к аналогии с кинотеатром, есть два способа получить билет: покупка
в кинотеатре и покупка онлайн. Выбранный метод влияет на последовательнось действий для получения
билета. Покупка в театре выглядит так:

  • приехать к кинотеатру;
  • войти в него;
  • пройти к кассе;
  • найти сеанс;
  • пообщаться с сотрудником кассы;
  • оплатить;
  • получить билет.

Покупка
онлайн:

  • перейти на сайт театра;
  • найти сеанс;
  • добавить билет в заказ;
  • оплатить;
  • получить билет на e-mail.

Разрешения (grants) диктуют клиенту порядок операций по получению access-токена. Этот уникальный порядок называется потоком.

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

  • Код разрешения авторизации (Authorization Code Grant) – наиболее распространенный тип разрешений (Рис. 4). Клиент получает уникальный код, выданный сервером авторизации, который затем обменивается на токен.
  • Код разрешения авторизации с PKCE – этот вариант используется для публичных клиентов, которым нельзя доверять хранение учетных данных. Используя расширение PKCE (Public Key for Code Exchange), клиент и сервер обмениваются хэшем, чтобы убедиться, что связь не скомпрометирована.
  • Учетные данные клиента – иногда клиенты запрашивают доступ для себя, а не для владельца ресурса. Эти экземпляры используют внутренние службы, которым требуется доступ к облачному хранилищу. В этом случае клиент сделает запрос, включающий client_id и client_secret, которые сервер авторизации проверяет для выдачи access-токенов. Этот тип разрешений должен использоваться только с конфиденциальными клиентами.
  • Код устройства – используется для устройств, подключенных к интернету, которые не имеют браузеров или снабжены неудобными виртуальными клавиатурами, например, игровая консоль или Smart TV.

Реализация скрипта на python

Блок 1 настройки серверов авторизации

service_config={"google":{'code':"",'url_token':"https://accounts.google.com/o/oauth2/token",'url_user_info':"https://www.googleapis.com/oauth2/v1/userinfo",'client_id':"....",'client_secret':"...",'redirect_uri':"http://...",'grant_type':'authorization_code'},"yandex":{'code':'','url_token':'https://oauth.yandex.ru/token','url_user_info':'https://login.yandex.ru/info','grant_type':'authorization_code','client_id':'...','client_secret':"..."},"facebook":{'code':'','url_token':'https://graph.facebook.com/oauth/access_token','url_user_info':'https://graph.facebook.com/me','client_id':'...','client_secret':'...','redirect_uri':"http://..."},"vkontakte":{'code':'','url_token':'https://oauth.vk.com/access_token','url_user_info':'https://api.vk.com/method/users.get?fields=uid,first_name,last_name,nickname,screen_name,sex,bdate,city,country,timezone,photo','client_id':'...','client_secret':'...','redirect_uri':"http://..."}}

Для настройки ОАuth авторизации через другой сервер (не приведенный в листинге) – просто добавить соотвествующие настройки

Блок 2 функция прохождения авторизации

Помним, что функция запускается, когда пользователь ввел логин-пароль на сервере авторизации и произошел редерикт по адресу, указанному нами при регистрации сайта. По данному адресу был направлен GET запрос, включающий параметры (агрумент вызова функции)

 1 importrequests 2 defstart(params): 3 # ШАГ 1 проверяем, заданы ли настройки авторизации для сервиса с которого пришел GET 4 # (см значение state) 5 ifnotparams['state']inservice_config: 6 return'' 7  8 # ШАГ 2 отсылаем запрос на получение ключа авторизации 9 headers={'Content-type':'application/x-www-form-urlencoded'}10 service_config[params['state']]['code']=params['code']11 r=requests.post(service_config[params['state']]['url_token'],data=service_config[params['state']],headers=headers)12 13 # если неверно заданы параметры приложения в service_config сервер авторизации вернет словарь с ключем error14 if'error'inr.text:15 return'Параметры приложения заданы неверно'16 17 # ШАГ 3 отсылаем запрос на получение информации о пользователе18 ifparams['state']=='facebook':19 # facebook отдает данные не json а в канонической форме - отсюда условие20 param_token=dict([i.split('=')foriinr.text.split('&')])21 # user_id нужно только для ВКонтакте, но мы же делаем универсальный скрипт22 user_id=''23 else:24 param_token=r.json()25 user_id=r.json().get('user_id','')26 27 r=requests.get(service_config[params['state']]['url_user_info'],params={'access_token':param_token['access_token'],'user_ids':user_id,'format':'json','oauth_token':param_token['access_token']})28 returnr.json()

Основная задача выполнена – пользователь идентифицировал себя через ОАuth, нужные данные о нем мы получили. Если не стоит задача куда-либо сохранять эти данные, то на этом можно остановиться.

Блок 3 приведение данных о пользователе к единой форме

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

  1. создаем для каждого сервера авторизации необходимую функцию, обрабатывающую переданную информацию о пользователе. В качестве обязательных параметров функции передаются:
    • param_token – ответ сервера авторизации с access_token (см. выше шаг 2). VKontakte передает адрес почты пользователя в access_token
    • param_info – собственно данные о пользователе,

Вот пример функций для рассматриваемых серверов авторизации

  1. Связываем каждую функцию со значением параметра state (см. выше)
  1. В основной функции (блок 2) добавляем строку

Теперь информация о пользователе возвращается в структурированном виде.

Регистрация приложения и его параметры

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

Руководство Django Часть 8: Аутентификация и авторизация пользователя - Изучение веб-разработки | MDN
После регистрации приложения вам выдается 5 параметров, которые требуются для работы с OAuth. Вот как они могут выглядеть:

Руководство django часть 8: аутентификация и авторизация пользователя – изучение веб-разработки | mdn

Django предоставляет систему аутентификации и авторизации (“permission”) пользователя, реализованную на основе фреймворка работы с сессиями, который мы рассматривали в предыдущей части. Система аутентификации и авторизации позволяет вам проверять учётные данные пользователей и определять какие действия какой пользователь может выполнять. Данный фреймворк включает в себя встроенные модели для Пользователей и Групп (основной способ применения прав доступа для более чем одного пользователя), непосредственно саму систему прав доступа (permissions)/флаги, которые определяют может ли пользователь выполнить задачу, с какой формой и отображением для авторизованных пользователей, а так же получить доступ к контенту с ограниченным доступом.

Примечание: В соответствии с идеологией Django система аутентификации является очень общей и, таким образом, не предоставляет некоторые возможности, которые присутствуют в других системах веб-аутентификации. Решениями некоторых общих задач занимаются пакеты сторонних разработчиков, например, защита от подбора пароля (через стороннюю библиотеку OAuth).

В данном разделе руководства мы покажем вам реализацию аутентификации пользователя на сайте LocalLibrary, создание страниц входа/выхода, добавления разграничения доступа (permissions) к вашим моделям, а также продемонстрируем контроль за доступом к некоторым страницам. Мы будем использовать аутентификацию/авторизацию для показа пользователям и сотрудникам библиотеки, списков книг, которые были взяты на прокат.

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

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

Сервер авторизации

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

Создание приложения

В начале использования OAuth процесса, вы должны зарегистрировать новое приложение в сервисе. При регистрации обычно определяется общая информация, такая как название, сайт, логотип и т.д. Дополнительно необходимо указать  URI перенаправления, который будет использован для перенаправления пользователей на веб-сервер, браузер или мобильное приложение.

Сообщение = документ цифровая подпись

«Цифровая подпись» — звучит страшно, но на самом деле это достаточно очевидная вещь. Когда вы ручкой подписываетесь на каком-либо документе, вы удостоверяете, что этот документ написан вами, а не кем-то другим. Ваша подпись как бы «добавляется» к документу и идет с ним в «одном комплекте».

Аналогично, цифровая подпись добавляется к некоторому блоку данных, удостоверяя: тот, кто сформировал эти данные, не выдает себя за другого. Цифровая подпись не шифрует документ, она лишь гарантирует его подлинность! Поставить подпись позволяет тот самый Shared Secret, который известен получателю и отправителю, но более никому.

Как это работает? Пусть наш $sharedSecret = 529AeGWg, и мы сообщили его шепотом на ухо принимающей стороне. Мы хотим передать сообщение «Мой телефон 1234567» с гарантированной защитой от фальсификации злоумышленником.

  1. Consumer добавляет цифровую подпись к сообщению, в общем виде —
    $transfer = $message . "-" . md5($message . $sharedSecret);
    // $transfer = "Мой телефон 1234567" . "-" . md5("Мой телефон 1234567" . "529AeGWg")
  2. Service Provider принимает данные, разбивает их обратно на 2 части — $message и $signature — и проделывает точно такую же операцию:
    $signatureToMatch = md5($message . $sharedSecret);
    // $signatureToMatch = md5("Мой телефон 1234567" . "529AeGWg");

    Дальше остается только сравнить получившееся значение $signatureToMatch с тем, что было в полученных данных $signature и рапортовать о подделке, если значения не совпали.

Стороннее приложение: клиент

Клиент это приложение которое пытается получить доступ к учетной записи пользователя. Для этого клиенту нужны разрешения от пользователя.

Терминология oauth

Разберем несколько
общих терминов. Для упрощения под OAuth будем подразумевать OAuth 2.0.

Фундамент oauth

Примечательно, что «подводных граблей» осталось еще много. Я не буду их здесь описывать, потому что эти грабли лежат в Марианской впадине (глубоко, 10920 м). На описание уязвимостей пришлось бы потратить с десяток страниц. Так что я сразу перейду к описанию OAuth, где все проблемы уже решены.

Функционирование протокола oauth

OAuth создан для
предоставления сторонним приложениям ограниченного доступа к защищенным
ресурсам без риска для данных пользователя. Это похоже на то, как работает режим
Valet Mode в Tesla.

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

Чем oauth отличается от openid?

OAuth часто называют «протоколом для роботов», в отличие от OpenID — «протокола для пользователей». Не путайте их!

Яндекс

1. Идем

Заключение

На текущий момент протокол широко распространен и активно развивается — в сервисах соцсетей, Google, IoT-сервисах для устройств умного дома и других. Наиболее полно его возможности раскрываются при интеграции с серией сервисов одного поставщика (например, Google), где вашему приложению можно с легкостью добавлять новые интеграции, используя те же учетные данные.

Автор текста: Роман Андреев.

Конец скрипта: вывод виджета

Окончание скрипта должно быть понятно и без подробных разъяснений.

Похожее:  Использование системы аутентификации Django | Документация Django 4.0 | Все о фреймворке Джанго и его библиотеках

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *