Как SPA извлекает токен доступа в неявном потоке OAuth2 - PullRequest
0 голосов
/ 11 мая 2018

У меня есть угловой SPA, и я хочу использовать неявный поток OAuth2 Неявный поток OAuth2

С авторизованным сервером авторизации, если у меня активная сессия с ним и я отправляю, поместите этот URL в адресную строку браузера

https://server.example.com/authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1

Я правильно перенаправлен с access_token на

 HTTP/1.1 302 Found
 Location: http://client.example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAAs&state=xyz&token_type=example&expires_in=3600

В спецификации указывается, что client.example.com/cb должен возвращать веб-страницу (обычно документ HTML со встроенным скриптом), способную получить доступ к URI полного перенаправления, включая фрагмент, сохраненный пользовательским агентом, и извлечь маркер доступа. Я реализовал страницу со скриптами, получающими access_token от window.location.hash, и она работает.

Теперь, поскольку SPA уже загружен, и мне также нужно сделать это для обновления токенов, я хочу сделать это с помощью запроса ajax. Однако с ajax, перенаправление выполняется автоматически, и я получаю только HTML-страницу, но access_token теряется. Я вижу access_token в заголовке Location ответа, но не знаю, как получить к нему доступ.

Auth0 и Okta , кажется, поддерживают тихую аутентификацию с использованием неявного потока, как они это делают?

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 12 мая 2018

Доступ к access_token возможен только через location.hash, и запрос ajax не будет обновлять это, поэтому не было никакого способа, которым это могло бы быть достигнуто через запрос ajax.

Посмотрел, как это делают другие библиотеки, и нашел это: https://github.com/damienbod/angular-auth-oidc-client#silent-renew

Хитрость заключалась в том, чтобы создать скрытый iframe и всякий раз, когда требуется токен, обновлять атрибут src до созданного URL. Токен будет доступен в пределах iframe, просто передайте его window.parent.

Для этого сначала присоедините прослушиватель событий к window

window.addEventListener("message", receiveToken, false);

function receiveToken(event) {
  // event.data will contain hash value
  console.log ('token received ' + event.data) ;
}

и вызывать эту функцию всякий раз, когда нужен новый токен

function fetchToken() {
    document.getElementById('iframe').src='https://server.example.com/authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb'
}

в то время как http://client.example.com/cb должно возвращать что-то вроде этого

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
    window.parent.postMessage(location.hash, "http://client.example.com");
</script>
</head>
<body></body>
</html>

второй аргумент postMessage здесь targetOrigin, он должен совпадать с именем хоста, где расположен SPA. Если вы не хотите, чтобы это ограничение безопасности было установлено на '*'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...