Итак, я разрабатываю API , используя slim/slim
и league/oauth2-server
для управления OAuth2 . OAuth2 будет полезен, потому что мне нужно будет использовать Предоставление клиентских учетных данных между сервисами.
Затем я также разрабатываю гибридное приложение с React Native . Это приложение требует входа пользователя в систему с использованием электронной почты и пароля или подключения к другим службам (таким как Facebook, Google, Twitter и т. Д.).
И я не совсем понимаю, какой поток OAuth2 использовать в этом случае,В Интернете много статей о том, что Учетные данные для пароля владельца ресурса больше не безопасны, и мы должны вместо этого использовать Код аутентификации с PKCE .
Но я могуВы не можете понять или понять, как применять код аутентификации с PKCE в приложении стороннего производителя, потому что во всей документации о вас потребуется браузер для получения кода аутентификации в redirect_uri
.
Поток, который я представляю, таков:что-то вроде этого:
- Пользователь открывает приложение, затем вводит свои учетные данные
username
и password
; - Этот экран подключится к API
/request_token
Отправка URI { 'grant_type': 'password', 'username': username, 'password': password, 'client_id': CLIENT_ID }
рассматривая его как общедоступное приложение, мы не можем отправить client_secret
; - API проверяет учетные данные и возвращает некоторые данные, такие как
{ "access_token": access_token, "token_type": "JWT", "expires_in": LIFE_SPAN }
, здесь мы будем использовать JWT , чтобы гееренироватьaccess_token
на основе public/private key
; - Аутентификация завершена, приложение будет хранить
access_token
, пока оно живое, а по истечении этого срока будет передавать refresh_token
.
Мой вопрос: это безопасно? Скотт Брэди сделал какую-то "агрессивную" статью, в которой говорилось, что она НИКОГДА не безопасна .
Как приложения это делают? Когда я использую приложение Instagram, например, они владеют приложением и API, мне не нужен браузер в потоке взаимодействия с пользователем. Используются ли в современных приложениях «Учетные данные пароля владельца ресурса» или «Код аутентификации с помощью PKCE»? Есть ли возможность избежать вставки браузера в поток при использовании «Аутентификационного кода с PKCE»?
[EDIT] Возможное решение
Как сказал Гари Арчер "Код авторизации"рекомендуется работать с PKCE - вместе с входом в систему через системный браузер ", но мы не говорим о предоставлении разрешений для доступа к данным пользователей или сторонним приложениям.
Как дизайнер, я не согласен с тем, что logginв первом приложении, принадлежащем тому же владельцу API, требуется браузер, это не тот пользовательский интерфейс, который мы ищем. И все приложения, которые мы видим, такие как Instagram, Facebook, Uber ... мы просто вводим ваше имя пользователя и пароль, и у нас есть доступ к вашей учетной записи.
Что я сделаю, это создаю собственную версию кода аутентификации с помощью PKCEудаление required_uri
.
[РЕДАКТИРОВАТЬ: 2] Новый поток
После долгих поисков я нашел несколько ответов, которые я думаю, было бы интересно адаптировать. Как и выше, я удалил redirect_url
из потока. Смотрите:
- Поток запускается на экране входа в систему, когда пользователь вводит ваши учетные данные;
Клиент генерирует code_verifier
, затем хэширует code_verifier
до code_challenge
иотправляет его на сервер авторизации со следующими параметрами:
response_type=code
: указывает, что ваш сервер ожидает получить код авторизации. client_id=xxxx
: идентификатор клиента. client_integrity=xxxx
: проверка целостности приложения для собственного приложения. code_challenge=xxxx
: вызов кода, сгенерированный, как описано выше. code_challenge_method=S256
: обычный или S256, в зависимости отот того, является ли вызов простой строкой верификатора или хешем SHA256 строки. Если этот параметр пропущен, сервер примет простое значение. username=xxxx
: имя пользователя для аутентификации. password=xxxx
: хешированная версия пароля. state=xxxx
: случайная строка, сгенерированная вашим приложением (защита CSRF).
Сервер авторизации проверит аутентификацию пользователя, сохранит code_challenge
и возвратит authorization_code
с client_token
;
После получения aauthorization_code
и client_token
Клиент сохраняет client_token
и немедленно отправляет authorization_code
обратно на Сервер авторизации со следующими параметрами:
grant_type=authorization_code
:указывает тип предоставления этого запроса токена. code=xxxx
: клиент отправит полученный код авторизации. client_id=xxxx
: идентификатор клиента. code_verifier=xxxx
: верификатор кода для запроса PKCE, который клиент изначально сгенерировал перед запросом авторизации.
Сервер авторизации проверит все данные и, если все правильно, выполнитверните access_token
;
- Клиент установит заголовок авторизации с
access_token
и всегда отправляет client_token
на каждый запрос, он будет принят только с обоими правильными значениями; - Если срок действия
access_token
истекает, то Клиент выполнит запрос на обновление access_token
и получит новый.
Теперь я воспроизведу эту логику на языке PHP. Если все пойдет хорошо, и я надеюсь, что это произойдет, я вернусь с окончательным ответом.
[РЕДАКТИРОВАТЬ] Уточнения
Я использую OAuth2 для подключения пользователя к сторонним аккаунтам (Google, Facebook и т. д.). Но пользователь также может войти в локальную учетную запись в моей базе данных. В этом случае пользователю вообще не нужно ничего предоставлять. Так что, нет смысла отправлять пользователю в браузер, чтобы он делал свой логин.
Интересно, можно ли в этом случае использовать локальные учетные записи Учетные данные для пароля владельца ресурса или это более безопасно Код аутентификации с помощью PKCE (мы уже заключаем, что этолучше подойдет). Но для кода аутентификации с PKCE требуется redirect_uri
. Нужно ли использовать это перенаправление для входа пользователей в локальную учетную запись, где им не нужно предоставлять доступ?