Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我如何在Angular中显示未经授权访问的错误页面?_Angular_Typescript_Authorization - Fatal编程技术网

我如何在Angular中显示未经授权访问的错误页面?

我如何在Angular中显示未经授权访问的错误页面?,angular,typescript,authorization,Angular,Typescript,Authorization,我正在一个角度应用程序中使用authz。我们大量使用路由,所以在路由守卫中检查授权似乎是有意义的 我是通过canActivateChild路径来实现的,设置大致如下: class MyGuard implements CanActivateChild { canActivateChild(route, state) { return !route.data || route.data.active; } } const routes: Routes = [ {

我正在一个角度应用程序中使用authz。我们大量使用路由,所以在路由守卫中检查授权似乎是有意义的

我是通过
canActivateChild
路径来实现的,设置大致如下:

class MyGuard implements CanActivateChild {
    canActivateChild(route, state) {
      return !route.data || route.data.active;
    }
}

const routes: Routes = [
  {
    path: '',
    canActivate: [MyGuard],
    canActivateChild: [MyGuard],
    children: [
      {
        path: 'hello', component: HelloComponent, data: { active: false }
      }
    ]
  }
]
class MyGuard implements CanActivateChild {
    canActivateChild(route, state): boolean | Observable<boolean> {
      if (!route.data || route.data.active) {
        // TODO: return your modal observable here and map it to boolean, e.g. via:
        return modalService.alert('Data error').map(() => false);
      }
      return true;
    }
}
(这显然大大简化了,但我认为如何确定路线是否得到授权的细节并不相关。一个更完整的工作示例是StackBlitz上的)

我的问题是,当授权失败时,route guard只允许我做两件事:返回
false
,让导航完全取消并保持在原始路线上;或者重定向到其他URL

我想要的UI显示了一条错误消息,但在用户试图导航到的URL下。(即,如果设置权限时出现错误,用户更容易报告“嘿,我无法访问此URL”,然后重新加载页面。)实际上,我希望服务器返回HTTP 403状态和正文


我考虑过不在路线上进行检查,让目标组件本身显示其他内容。我不是特别喜欢这个,如果没有其他原因的话,它会干扰模块的按需加载。有没有一种“干净”的方法可以从路由器上做到这一点?

我知道这不是您等待的响应,但我质疑其原理。Angular中的路由确保一个重要的不变量始终为真:路由中使用的组件通过路由表给出。这就是为什么你没有找到一个简单的方法来完成你的计划

我的猜测是,偏离这一原则就是要求在今后的道路上出现可维护性和/或可靠性问题

我将以下内容视为您最初愿望的解决方案:将失败的请求路由到
的/initial/path/failed
,此路由的组件包含可能对IT团队有用的错误数据

然后,在
的/initial/path/failed
路由中,您设置了一个反向保护:如果权限正常,则重定向到
的/initial/path

这样,就不会破坏路由宇宙核心的角度不变量

这一过程类似于未登录时回滚到登录页面,如果已登录则跳过登录页面

编辑: 我在评论中看到了你的观点,我基本上同意你的观点。 不过,为了尝试推进解决方案,这里有一个可接受的非样板近似:

创建一个简单的“失败”组件。它显示从服务获取的消息(典型的组件间消息传递,类似于flash消息功能)。谨防:

router.navigate(...).then(_ =>
  Service.post_flash_message('instructions with "retry" link to initial url'));

这不完全是你的要求,而是迈向目标的一步。

再加上一个想法:你是否考虑过在守卫中返回一个新的可观察目标?角度防护装置可以返回
布尔值
,也可以返回
可观察值
。这样,在拒绝路由导航之前,您可以通过显示带有错误/警告消息的模式来延迟实际路由过程

这可以通过以下方式实现:

class MyGuard implements CanActivateChild {
    canActivateChild(route, state) {
      return !route.data || route.data.active;
    }
}

const routes: Routes = [
  {
    path: '',
    canActivate: [MyGuard],
    canActivateChild: [MyGuard],
    children: [
      {
        path: 'hello', component: HelloComponent, data: { active: false }
      }
    ]
  }
]
class MyGuard implements CanActivateChild {
    canActivateChild(route, state): boolean | Observable<boolean> {
      if (!route.data || route.data.active) {
        // TODO: return your modal observable here and map it to boolean, e.g. via:
        return modalService.alert('Data error').map(() => false);
      }
      return true;
    }
}
MyGuard类实现了CanActivateChild{ canActivateChild(路由、状态):布尔值|可观察{ 如果(!route.data | | route.data.active){ //TODO:在此处返回模态可观测值并将其映射为布尔值,例如通过: 返回modalService.alert('Data error').map(()=>false); } 返回true; } }
实际上,我在我的应用程序中使用了这个模式,允许用户在模式中更新他们的令牌/登录(如果警卫检测到令牌过期,这很可能会导致服务器API错误),然后在获取新令牌后继续导航。防护装置将“悬挂”,直到可观察物发出
true
false

这确实不是我想要的答案。我正在为用户而不是框架作者构建应用程序。我需要一个比含糊其辞的“这可能会导致问题”更强烈的警告——你写的每一行代码都可能。据我所知,Ng路由不允许像
**/failed
这样的路由,因此您的方法似乎需要大量的样板文件,这很难成为维护的福音。我还认为所谓的与用户登录相似之处并不十分合适。未经身份验证的用户可能会采取措施纠正该问题-登录-这就是为什么他们会绕道登录页面并返回。对于未经授权的用户,他们可能不会采取任何行动,他们可能正在访问不应该访问的资源,或者管理员必须授予他访问权限;他们从一开始就处于死胡同,所以增加更多的步骤是没有意义的。如果有帮助的话,用一个额外的想法编辑我的答案。虽然我不太同意这个框架。当你选择一个有观点的框架时,你要么按规则行事,要么就开辟了一些困难的道路。这不是事实,而是经验,我同意这不是100%有效的。但我发现,当我陷入这种状态时,框架中通常有一个可接受的解决方案。你可以确定从A到B只能向后行驶,但这将是一个地狱般的旅程:)如果用户只是冷导航到一个未经授权的URL,比如在一个新选项卡中打开一个链接,这会做什么?我们确实有一个toast通知实用程序,但我真的不知道Ng是否会呈现任何内容。稍后我将保留这个技巧,但我必须强调这是授权,而不是身份验证。用户在应用程序UI中无需执行任何操作即可访问资源,如果他应该拥有资源,则管理员必须授予他相应的角色,并且用户必须硬加载才能加载新功能。