Введение в OAuth 2
Оригинальная публикации: https://www.digitalocean.com/community/tutorials/oauth-2-ru
Введение
OAuth 2 представляет собой фреймворк для авторизации, позволяющий приложениям осуществлять ограниченный доступ к пользовательским аккаунтам на HTTP сервисах, например, на Facebook, GitHub и DigitalOcean. Он работает по принципу делегирования аутентификации пользователя сервису, на котором находится аккаунт пользователя, позволяя стороннему приложению получать доступ к аккаунту пользователя. OAuth 2 работает в вебе, на десктопных и мобильных приложениях.
Эта статья предназначена для разработчиков приложений и предоставляет обзор ролей, типов авторизации и типичных сценариев использования OAuth 2.
Роли OAuth
Далее мы рассмотрим каждую из ролей.
Владелец ресурса: Пользователь
Владельцем ресурса является пользователь, который авторизует приложение для доступа к своему аккаунту. Доступ приложения к пользовательскому аккаунту ограничен “областью видимости” (scope) предоставленных прав авторизации (например, доступ на чтение или запись).
Сервер ресурсов / авторизации: API
Сервер ресурсов непосредственно хранит защищённые данные аккаунтов пользователей, а авторизационный сервер проверяет подлинность информации, предоставленной пользователем, а затем создаёт авторизационные токены для приложения, с помощью которых приложение будет осуществлять доступ к пользовательским данным.
С точки зрения разработчика приложения API сервиса одновременно выполняет и роль сервера ресурсов и роль сервера авторизации. Далее мы будем считать эти две роли одной, и называть её Сервис или API.
Клиент: Приложение
Клиентом является приложение, которое хочет осуществить доступ к аккаунту пользователя. Перед осуществлением доступа приложение должно быть авторизовано пользователем, а авторизация должна быть одобрена со стороны API.
Абстрактное описание протокола
Теперь, когда у нас есть представление о ролях, используемых в OAuth, рассмотрим диаграмму их взаимодействия друг с другом.
Рассмотрим описание последовательности шагов на этой диаграмме:
- Приложение запрашивает у пользователя авторизацию на доступ к серверу ресурсов.
- Если пользователь авторизует запрос, приложение получает разрешение на авторизацию (authorization grant).
- Приложение запрашивает авторизационный токен у сервера авторизации (API) путём предоставления информации о самом себе и разрешении на авторизацию от пользователя.
- Если подлинность приложения подтверждена и разрешение на авторизацию действительно, сервер авторизации (API) создаёт токен доступа для приложения. Процесс авторизации завершён.
- Приложение запрашивает ресурс у сервера ресурсов (API), предоставляя при этом токен доступа для аутентификации.
- Если токен действителен, сервер ресурсов (API) предоставляет запрашиваемый ресурс приложению.
Фактический порядок шагов описанного процесса может отличаться в зависимости от используемого типа разрешения на авторизацию, но в целом процесс будет выглядеть описанным образом. Далее мы рассмотрим различные типы разрешений на авторизацию.
Регистрация приложения
Перед тем, как начать использовать OAuth в вашем приложении, вам необходимо зарегистрировать своё приложения в сервисе. Это делается путём регистрации в разделе “developer” или “API” сайта сервиса, где вам необходимо предоставить следующую информацию (возможно, включая некоторые детали о вашем приложении):
Redirect URL - это URL, на который сервис будет перенаправлять пользователя после авторизации (или отказа в авторизации) вашего приложения.
Идентификатор клиента и секрет клиента
После регистрации приложения сервис создаст учётные данные клиента - идентификатор клиента (client ID) и секрет клиента (client secret). Идентификатор клиента представляет собой публично доступную строку, которая используется API сервиса для идентификации приложения, а также используется для создания авторизационных URL для пользователей. Секрет клиента используется для аутентификации подлинности приложения для API сервиса, когда приложение запрашивает доступ к аккаунту пользователя. Секрет клиента должен быть известен только приложению и API.
Разрешение на авторизацию
В абстрактном описании протокола выше первые четыре шага касаются вопросов создания разрешения на авторизацию и токена доступа. Тип разрешения на авторизацию зависит от используемого приложением метода запроса авторизации, а также от того, какие типы разрешения поддерживаются со стороны API. OAuth 2 определяет четыре разных типа, каждый из которых полезен в определённых ситуациях:
- Код авторизации (Authorization Code): используется с серверными приложениями (server-side applications).
- Неявный (Implicit): используется мобильными или веб-приложениями (приложения, работающие на устройстве пользователя).
- Учётные данные владельца ресурса (Resource Owner Password Credentials): используются доверенными приложениями, например приложениями, которые являются частью самого сервиса.
- Учётные данные клиента (Client Credentials): используются при доступе приложения к API.
Далее мы рассмотрим эти типы разрешения на авторизацию, примеры их использования.
Тип разрешения на авторизацию: Код авторизации
Код авторизации является одним из наиболее распространённых типов разрешения на авторизацию, поскольку он хорошо подходит для серверных приложений, где исходный код приложения и секрет клиента не доступны посторонним. Процесс в данном случае строится на перенаправлении (redirection), что означает, что приложение должно быть в состоянии взаимодействовать с пользовательским агентом (user-agent), например, веб-браузером, и получать коды авторизации API, перенаправляемые через пользовательский агент.
Шаг 1: Ссылка с кодом авторизации
Сначала пользователю предоставляется ссылка следующего вида:
https://cloud.digitalocean.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
- https://cloud.digitalocean.com/v1/oauth/authorize: входная точка API авторизации (API authorization endpoint).
- client_id=CLIENT_ID: идентификатор клиента приложения (с помощью этого идентификатора API понимает, какое приложение запрашивает доступ).
- redirect_uri=CALLBACK_URL: URL, на который сервис перенаправит пользовательского агент (браузер) после выдачи авторизационного кода.
- response_type=code: указывает на то, что приложение запрашивает доступ с помощью кода авторизации.
- scope=read: задаёт уровень доступа приложения (в данном случае - доступ на чтение).
Шаг 2: Пользователь авторизует приложение
Когда пользователь нажимает на ссылку, он должен сперва осуществить вход в систему для подтверждения своей личности (если он, конечно, ещё не залогинен). После этого сервис предложит пользователю авторизовать или отказать в авторизации приложению для доступа к аккаунту пользователя. Пример такого диалога представлен ниже:
На этом скриншоте экрана авторизации DigitalOcean мы можем видеть, что приложение “Thedropletbook App” запрашивает доступ на чтение к аккаунту “[email protected]”.
Шаг 3: Приложение получает код авторизации
Если пользователь выбирает “Авторизовать приложение”, сервис перенаправляет пользовательский агент (браузер) по URL перенаправления (redirect URL), который был задан на этапе регистрации клиента (вместе с кодом авторизации). Ссылка будет выглядеть похожим образом (в данном примере приложение называется “dropletbook.com”):
https://dropletbook.com/callback?code=AUTHORIZATION_CODE
Шаг 4: Приложение запрашивает токен доступа
Приложение запрашивает токен доступа у API путём отправки авторизационного кода и аутентификационной информации (включая секрет клиента) сервису. Ниже представлен пример POST-запроса для получения токена DigitalOcean:
https://cloud.digitalocean.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL
Шаг 5: Приложение получает токен доступа
Если авторизация прошла успешно, API возвращает токен доступа (а также, опционально, токен для обновления токена доступа - refresh token). Весь ответ сервера может выглядеть следующим образом:
{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read","uid":100101,"info":{"name":"Mark E. Mark","email":"[email protected]"}}
Теперь приложение авторизовано! Оно может использовать токен для доступа к пользовательскому аккаунту через API сервиса с заданными ограничениями доступа до тех пор, пока не истечёт срок действия токена или токен не будет отозван. Если был создан токен для обновления токена доступа, он может быть использован для получения новых токенов доступа, когда истечёт срок действия старого токена.
Тип разрешения на авторизацию: Неявный
Неявный тип разрешения на авторизацию используется мобильными и веб-приложениями (приложениями, которые работают в веб-браузере), где конфиденциальность секрета клиента не может быть гарантирована. Неявный тип разрешения также основан на перенаправлении пользовательского агента, при этом токен доступа передаётся пользовательскому агенту для дальнейшей передачи приложению. Это, в свою очередь, делает токен доступным пользователю и другим приложениям на устройстве пользователя. Также при этом типе разрешения на авторизацию не осуществляется аутентификация подлинности приложения, а сам процесс полагается на URL перенаправления (зарегистрированный ранее в сервисе).
Неявный тип разрешения на авторизацию не поддерживает токены обновления токена доступа (refresh tokens).
Процесс выглядит следующим образом: приложение просит пользователя авторизовать себя, затем сервер авторизации передаёт токен доступа к пользовательскому агенту, который передаёт токен приложению. Далее мы опишем процесс в деталях.
Шаг 1: Ссылка для неявной авторизации
При неявном типа разрешения на авторизацию пользователю предоставляется ссылка, запрашивающая токен у API. Эта ссылка выглядит почти так же, как ссылка для предыдущего способа (с кодом авторизации), за исключением того, что запрашивается токен вместо кода (обратите внимание на response type “token”):
https://cloud.digitalocean.com/v1/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
Шаг 2: Пользователь авторизует приложение
Когда пользователь нажимает на ссылку, он должен сперва осуществить вход в систему для подтверждения своей личности (если он, конечно, ещё не залогинен). После этого сервис предложит пользователю авторизовать или отказать в авторизации приложению для доступа к аккаунту пользователя. Пример такого диалога представлен ниже:
На этом скриншоте экрана авторизации DigitalOcean мы можем видеть, что приложение “Thedropletbook App” запрашивает доступ на чтение к аккаунту “[email protected]”.
Шаг 3: Пользовательский агент получает токен доступа с URI перенаправления
Если пользователь выбирает “Авторизовать приложение”, сервис перенаправляет пользовательский агент по URI пренправления приложения и включает в URI фрагмент, содержащий токен доступа. Это выглядит примерно вот так:
https://dropletbook.com/callback#token=ACCESS_TOKEN
Шаг 4: Пользовательский агент следует по URI перенаправления
Пользовательский агент следует по URI перенаправления, сохраняя при этом токен доступа.
Шаг 5: Приложение выполняет скрипт извлечения токена доступа
Приложение возвращает веб-страницу, которая содержит скрипт для извлечения токен доступа из полного URI перенаправления, сохранённого пользовательским агентом.
Шаг 6: Токен доступа передаётся приложению
Пользовательский агент запускает скрипт извлечения токена доступа, а затем передаёт извлечённый токен приложению.
Теперь приложение авторизовано! Оно может использовать токен для доступа к пользовательскому аккаунту через API сервиса с заданными ограничениями доступа до тех пор, пока не истечёт срок действия токена или токен не будет отозван.
Тип разрешения на авторизацию: учётные данные владельца ресурса
При этом типе разрешения на авторизацию пользователь предоставляет приложению напрямую свои авторизационные данные в сервисе (имя пользователя и пароль). Приложение, в свою очередь, использует полученные учётные данные пользователя для получения токена доступа от сервиса. Этот тип разрешения на авторизацию должен использоваться только в том случае, когда другие варианты не доступны. Кроме того, этот тип разрешения стоит использовать только в случае, когда приложение пользуется доверием пользователя (например, является частью самого сервиса, или операционной системы пользователя).
Процесс с учётными данными владельца ресурса
После того, как пользователь передаст свои учётные данные приложению, приложение запросит токен доступа у авторизационного сервера. Пример POST-запроса может выглядеть следующим образом:
https://oauth.example.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID
Если учётные данные корректны, сервер авторизации вернёт токен доступа приложению. Теперь приложение авторизовано!
Внимание: DigitalOcean в настоящее время не поддерживает тип разрешения на авторизацию с использованием учётных данных владельца ресурса, поэтому ссылка выше ведёт на воображаемый авторизационный сервер “oauth.example.com”.
Тип разрешения на авторизацию: Учётные данные клиента
Тип разрешения на авторизацию с использованием учётных данных клиента позволяет приложению осуществлять доступ к своему собственному аккаунту сервиса. Это может быть полезно, например, когда приложение хочет обновить собственную регистрационную информацию на сервисе или URI перенаправления, или же осуществлить доступ к другой информации, хранимой в аккаунте приложения на сервисе, через API сервиса.
Процесс с учётными данными клиента
Приложение запрашивает токен доступа путём отправки своих учётных данных, своего идентификатора клиента и секрета клиента авторизационному серверу. Пример POST-запроса может выглядеть следующим образом:
https://oauth.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET
Если учётные данные клиента корректны, авторизационный сервер вернёт токен доступа для приложения. Теперь приложение авторизовано для использования собственного аккаунта!
Пример использования токена доступа
После того, как приложение получит токен доступа, оно может использовать этот токен для доступа к пользовательскому аккаунту через API сервиса с заданными ограничениями доступа до тех пор, пока не истечёт срок действия токена или токен не будет отозван.
Ниже представлен пример запроса к API с использованием curl
. Обратите внимание, что он содержит токен доступа:
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN""https://api.digitalocean.com/v2/$OBJECT"
Если токен доступа валиден, API обработает полученный запрос. Если срок действия токена доступа истёк или токен некорректен, API вернёт ошибку “invalid_request”.
Обновление токена доступа
После истечения срока действия токена доступа все запросы к API с его использованием будут возвращать ошибку “Invalid Token Error”. Если при создании токена доступа был создан и токен для обновления токена доступа (refresh token), последний может быть использован для получения нового токена доступа от авторизационного сервера.
Ниже представлен пример POST-запроса, использующего токен для обновления токена доступа для получения нового токена доступа:
https://cloud.digitalocean.com/v1/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN
Заключение
На этом мы завершаем наш обзор OAuth 2. Теперь у вас есть общее представление о том, как работает OAuth 2, а также о том, когда и как использовать существующие типы разрешения на авторизацию.
Если вы хотите узнать больше об OAuth 2, рекомендуем ознакомиться со следующими статьями: