【发布时间】:2023-04-03 03:00:02
【问题描述】:
我们有一个基于 MVC 身份验证的 Angular 5 应用程序。该应用程序是从 Home/Index 操作提供的,一旦加载了应用程序,角度路由就会处理几乎所有事情。我们这样做主要是因为我们想使用 MVC 的身份验证过程(我们使用 Identity Server 4 作为我们的 Oath 系统)。
这很有效,但有一个例外:注销。当我们尝试注销时,应用程序似乎立即被重新授权并重新加载,而不是让我们返回到 Identity Server 登录页面。
最初,我们通过这段代码在我们的开发环境中取得了成功:
[HttpPost]
public async Task<IActionResult> Logout()
{
foreach (string key in Request.Cookies.Keys)
{
Response.Cookies.Delete(key);
}
await HttpContext.SignOutAsync();
return Ok();
}
但这是一个误报,因为我们所有的应用程序都在本地主机上运行,所以它们可以访问彼此的 cookie。因此,Identity Server cookie 与 Angular 应用程序的 cookie 一起被清除。
我们试图用这样的东西替换那个逻辑:
public async Task Logout()
{
if (User?.Identity.IsAuthenticated == true)
{
// delete local authentication cookie
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc");
}
}
但是,它在这两种环境中都没有注销(但是该代码适用于我们使用相同身份服务器的 MVC 应用程序之一)。
为了提供一些背景知识,我们的 Angular 应用程序的注销过程来自一个材质菜单,然后在调用注销函数之前,我们会在该菜单中提示用户他们是否真的想使用模式注销。这个过程的代码sn-ps:
注销按钮调用的方法:
public openDialog(): void {
let dialogRef = this.dialog.open(ModalComponent, {
width: '250px',
data: { text: this.logoutText, ok: this.okText, cancel: this.cancelText }
});
dialogRef.afterClosed().subscribe(result => {
if (result !== undefined) {
switch (result.data) {
case 'ok':
this.logout();
break;
case 'cancel':
break;
default:
break;
}
}
});
}
private logout(): void {
this.sessionService.logOut();
}
会话服务:
public logOut(): void {
this.auth.revokeToken();
this.http.post(this.logoutUrl, undefined).subscribe(x => window.location.reload());
}
如前所述,以这种方式调用注销最终会导致页面刷新并且用户并未真正注销。我们可能缺少一些简单的东西,但到目前为止我所做的所有修补都没有带来任何成功。
编辑:
我们的角度路由相当简单(尽管路径阻止我们调用 home/logout 之类的东西):
{
path: 'parts',
component: PartsComponent,
canActivate: [AuthGuard],
runGuardsAndResolvers: 'always',
data: { title: 'Parts' }
},
{
path: '',
redirectTo: 'parts',
pathMatch: 'full'
},
{
path: '**',
redirectTo: 'parts'
}
我们的 MVC 路线也相当简单
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
"Sitemap",
"sitemap.xml",
new { controller = "Home", action = "SitemapXml" });
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
我不确定我们如何能够以原来的角度路线轻松地路由到家/注销。我猜我们必须为它添加一条路线。我们曾经尝试过,但它从未正确路由。我正在尝试查找有关我们尝试过的内容的笔记。
【问题讨论】:
-
当页面刷新时,用户是否注销?还是他仍然登录,但页面刚刚刷新?
-
@dAxx_ 它清除 Angular 应用程序的 cookie。刷新后地址栏中显示的 URL 是登录页面的 URL(包括重定向查询字符串),但它从不显示登录页面,只是再次重定向到 Angular 应用程序,就好像用户已经登录一样。
-
您没有提供任何路由配置或守卫,但您使用其中任何一个吗?在您的 http.POST 中,您只需执行一个 window.loaction.reload(),这不是服务的工作,您应该将 Observable 返回给组件,并在那里订阅它。通过路由器执行到登录组件的导航。
-
@MarshallTigerus 您的 ajax 请求可能只清除客户端应用程序 cookie。要清除身份服务器 cookie,我认为您应该将用户重定向到注销页面。
-
添加了更多信息。
标签: asp.net-core angular5 identityserver4 logout