【发布时间】:2021-02-06 02:11:14
【问题描述】:
我有一个项目使用 Django 后端,使用 Django Rest Framework 提供 API,并使用 Vue.js 前端 SPA 来使用 API。我在身份验证期间遇到了某种 CORS 问题。
我一直在使用 mozilla-django-oidc 通过 Okta 实现授权代码流程。这几乎可以开箱即用,如果我在浏览器中导航到 API,我可以登录到 Okta 并获得一个 Django 会话。我还为 DRF 启用了 SessionAuthentication,它允许 SPA 访问由 Django 生成的相同会话 cookie(SPA 和 API 在同一个域中),前提是我首先通过 API 直接登录。这一切正常,直到 id 令牌过期。在 Django 中,当 id 令牌过期时,我会重定向到 https://example.okta.com/oauth2/v1/authorize?...,授权码流程完成,然后我会被发送到最初请求的页面。失败的地方是从 SPA 到具有过期 id 令牌的 API 的 ajax 请求。我得到了相同的重定向,但这次它由于 CORS 而失败。
Access to XMLHttpRequest at 'https://example.okta.com/oauth2/v1/authorize?response_type=code&client_id=X&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Foidc%2Fcallback%2F&state=X&scope=openid+email+profile&prompt=none&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.
我试图找出失败的原因。
在本地开发中,我在 127.0.0.1:8000 上运行我的 API,在 127.0.0.1:8080 上运行我的 SPA,所以很明显来源不匹配。我使用代理设置了 Vue,因此看起来请求来自 8080,但对 Okta 的请求中的 redirect_uri 仍在使用 8000。
当我部署到测试服务器时,我将 docker 容器用于 API 和 SPA,并使用反向代理来路由请求和 SSL。在这种情况下,API 和 SPA 具有相同的来源(我认为)。但我仍然收到相同的错误消息。
Access to XMLHttpRequest at 'https://example.okta.com/oauth2/v1/authorize?response_type=code&client_id=X&redirect_uri=http%3A%2F%2Fexample.com%2Foidc%2Fcallback%2F&state=X&scope=openid+email+profile&prompt=none&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 如何知道谁登录了?
编辑:我已经尝试将来源添加到 Okta 配置中的 Security > API > Trusted Origins 部分。没有骰子。
【问题讨论】:
标签: django vue.js cors openid-connect okta