我正在开发一个使用 Angular 作为前端和 Spring Boot 后端的 Web 应用程序。我们通过微软的身份平台实现了OAuth2登录。登录工作正常,但我在尝试实现注销时遇到了问题。
发生的情况如下(红色标记的框是我的问题):
https://login.microsoftonline.com/12345-345-450c-be26-e9df0d55c2fb/oauth2/v2.0/logout?id_token_hint=...&post_logout_redirect_uri=http://localhost:9000
Angular 客户端尝试访问此 URL,然后收到 CORS 错误:
Access to XMLHttpRequest at 'https://login.microsoftonline.com/...' (redirected from 'http://localhost:9000/logout') from origin 'http://localhost:9000' 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.
我不明白为什么 Angular 甚至试图像常规 HTTP 请求一样遵循重定向。难道不应该像典型的浏览器重定向一样处理吗?
知道这是怎么回事吗?更重要的是,我该如何解决这个问题?
提前谢谢您!
您应该观察 POST 请求的响应,并使用
window.location.href
标头的值设置 location
。比如:
async logout() {
lastValueFrom(this.http.post('/logout', null, { observe: 'response' }))
.then((resp) => {
const logoutUri = resp.headers.get('location') || '';
if (logoutUri) {
window.location.href = logoutUri;
}
});
}
请求来源将是 Keycloak(将窗口位置设置为外部 URI,“退出”你的 Angular 应用程序以“进入”新网站)。
当然,这个
logoutUri
应包含一个 redirect_uri
请求参数,指向您的 Angular 应用程序。
但是,要观察
response
,HTTP 状态必须在 2xx
范围内。为此,在本教程中,我重写了/logout
端点,如源代码中所示。
在链接的代码中,我使用我的组件来构建注销 URI,因为我支持不完全遵循 RP 发起的注销标准的授权服务器(Auth0 和 Amazon Cognito 来命名它们)。如果你不想使用“我的”starter,你可能会从
OidcClientInitiatedServerLogoutSuccessHandler
源代码中得到一些启发:Keycloak严格遵循RP-Initiated Logout。