【问题标题】:Check if route/url can be activated (and hide button)检查是否可以激活路由/url(并隐藏按钮)
【发布时间】:2023-01-11 20:05:01
【问题描述】:

使用 Angular 14,我的路由设置如下:

{ path: 'users', component: UsersComponent, canActivate: [AuthGuard], data: { role: 'user.read' } },

然后在 AuthGuard 中,如果经过身份验证的 jwt 不包含“user.read”范围,我将返回 false。这有效,如果用户没有范围,他们将被重定向到“/”。

现在我想从 UI 中删除“用户”页面按钮;我有路由器链接users,如何访问路由数据以检查页面是否可用;如果没有,则隐藏按钮。

我认为基本上我需要给定 url 的 ActivatedRouteSnapshot(传递给 CanActivate)——我看到的所有示例都需要 Router 订阅;但这只给了我当前的网址;不是我可能会去的那个。

SO 上的所有其他答案似乎基本上是在建议我在按钮上添加对“users.read”的检查;但我真的不想再添加它——它已经在路由中定义了。

似乎是一个简单的问题,但我正在努力寻找答案 - 谢谢!

【问题讨论】:

  • 在您的 AuthGuard 中,您可以设置 sessionStorage 变量,然后检查变量以隐藏/显示按钮。
  • 我什么时候设置sessionStorage?据我目前所知,canActivate 仅在我单击要隐藏的按钮后才被调用?

标签: angular


【解决方案1】:

您可以将检查 user.read 范围的逻辑移动到服务中,然后将该服务注入到 AuthGuard 和您的组件中。然后你只需在守卫的canActivate 函数中调用该函数,并使用它为组件中的按钮驱动一个*ngIf

【讨论】:

  • 不确定我是否遵循 - 我有一个函数可以从 jwt 读取范围;我需要的是找到相关路线并从中读取 data 对象......
【解决方案2】:

我写了这个函数来解决这个问题;这不是完整的答案,但使用此功能我可以获取给定 url 的路由数据并轻松比较范围。

似乎很生气我不得不写这个 - 这段代码显然在路由器目标代码中的某个地方,但我找不到它!仍然希望得到更好的答案;但这会让我度过难关,并且可能会帮助其他人!

此函数处理具有自定义匹配器和简单参数化路由的路由,但我确信还有许多其他路由选项未涵盖

它从router.config获取路由列表;在类构造函数中声明为private router: Router

matchRouteToUrl(url: string): Route | null {

    if (url[0] == '/') { url = url.slice(1); }
    let urlRoute = this.router.config.find(route => {
        
        if (route.path == url) {
            return true;
        }

        const urlSegmentGroup = this.router.parseUrl(url).root.children[PRIMARY_OUTLET];
        if (urlSegmentGroup) {
            const urlSegments = urlSegmentGroup.segments;

            if (route.matcher) {
                return route.matcher(urlSegments, urlSegmentGroup, route);
            }
            if (urlSegments.length > 1 && route.path?.includes(':')) {

                const pathSegmentGroup = this.router.parseUrl(route.path).root.children[PRIMARY_OUTLET];
                if (pathSegmentGroup) {
                    const pathSegments = pathSegmentGroup.segments;

                    if (urlSegments.length == pathSegments.length) {
                        let allSegmentsMatch = true;
                        for (let i = 0; i < urlSegments.length; i++) {
                            if (pathSegments[i].path[0] != ':' && urlSegments[i].path != pathSegments[i].path) {
                                allSegmentsMatch = false;
                            }
                        }
                        return allSegmentsMatch;
                    }
                }
            }
        }
        return false;
    });

    return urlRoute || null;
}

【讨论】:

    猜你喜欢
    • 2019-10-15
    • 2012-03-28
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多