#django #vue.js #cors #openid-connect #okta
#django #vue.js #cors #OpenID-подключение #okta
Вопрос:
У меня есть проект, использующий серверную часть Django, с фреймворком Django Rest для обслуживания API и Vue.js интерфейс SPA для использования API. Я столкнулся с какой-то проблемой CORS во время аутентификации.
Я использовал mozilla-django-oidc для реализации потока кода авторизации с помощью Okta. Это отлично работает практически из коробки, и если я перейду к API в своем браузере, я могу войти в Okta и получить сеанс Django. Я также включил SessionAuthentication для DRF, что позволяет SPA получать доступ к тем же сеансовым файлам cookie, сгенерированным Django (и SPA, и API находятся в одном домене), при условии, что я сначала войду в систему напрямую через API. Все это работает нормально, пока не истечет срок действия токена id. В Django, когда срок действия токена id истекает, я получаю перенаправление https://example.okta.com/oauth2/v1/authorize?...
, поток кода авторизации завершается, и меня отправляют на первоначально запрошенную страницу. Сбой происходит в запросе ajax от SPA к API с истекшим идентификатором id. Я получаю то же перенаправление, но на этот раз оно завершается с ошибкой из-за CORS.
Access to XMLHttpRequest at 'https://example.okta.com/oauth2/v1/authorize?response_type=codeamp;client_id=Xamp;redirect_uri=http://127.0.0.1:8000/oidc/callback/amp;state=Xamp;scope=openid email profileamp;prompt=noneamp;nonce=X' (redirected from 'http://127.0.0.1:8080/api/X') from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Я попытался определить, почему это не удается.
При локальной разработке я использую свой API на 127.0.0.1: 8000, а свой SPA на 127.0.0.1: 8080, поэтому очевидно, что происхождение не совпадает. У меня есть настройка Vue с прокси, поэтому похоже, что запросы поступают с 8080, но redirect_uri в запросе к Okta по-прежнему использует 8000.
При развертывании на тестовом сервере я использую контейнеры docker для API и SPA и обратный прокси-сервер для маршрутизации запросов, а также для SSL. В этом случае API и SPA имеют одинаковое происхождение (я думаю). Тем не менее, я все еще получаю то же сообщение об ошибке.
Access to XMLHttpRequest at 'https://example.okta.com/oauth2/v1/authorize?response_type=codeamp;client_id=Xamp;redirect_uri=http://example.com/oidc/callback/amp;state=Xamp;scope=openid email profileamp;prompt=noneamp;nonce=X' (redirected from 'https://example.com/api/X') from origin 'https://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Если вы заметили, redirect_uri — это http, а не https. Я подозреваю, что именно поэтому это не удается. Хотя я не совсем уверен, потому что, если я перейду в свой браузер к API, я использую https, но redirect_uri по-прежнему http, и он по-прежнему успешно проходит аутентификацию.
Любая информация была бы действительно полезной.
- Что я делаю не так или чего здесь не хватает?
- Я неправильно подхожу к процессу аутентификации для приложения API SPA? Должен ли я вместо этого выполнять аутентификацию в SPA? Как тогда API узнает, кто вошел в систему?
Редактировать: я уже пытался добавить источники в раздел Безопасность> API> Доверенные источники в конфигурации Okta. Нет кубиков.
Ответ №1:
https://developer.okta.com/docs/guides/enable-cors/overview/
В Okta CORS позволяет JavaScript, размещенному на ваших веб-сайтах, отправлять запрос с помощью XMLHttpRequest к Okta API с помощью файла cookie сеанса Okta. Каждый источник веб-сайта должен быть явно разрешен как доверенный источник.
Поэтому правильно настройте свои надежные источники в конфигурации клиента Okta.
Комментарии:
1. Ах да, я забыл написать в исходном сообщении, что я добавил origins в Trusted Origins, и все равно ничего. Я не уверен, но я думаю, что Okta «API» — это нечто иное, чем поток авторизации. По крайней мере, документация для них, похоже, состоит из отдельных разделов.
Ответ №2:
Вы выполняете AJAX-вызов / авторизацию? Это может быть причиной ошибки.
Как упоминалось здесь, при отправке запросов к конечной точке /authorize браузер (агент пользователя) должен перенаправляться на конечную точку. Вы не можете использовать AJAX с этой конечной точкой.
Комментарии:
1. Да, я думаю, это может быть проблемой. Я не делаю AJAX-вызов / авторизовать себя, но я делаю AJAX-вызов для серверной части, который перенаправляет на / авторизовать. Но это перенаправление на самом деле не выполняется в браузере, и я получаю ошибку CORS. В любом случае, с тех пор я немного изменил свой поток, чтобы это больше не было проблемой для меня.