首页 > 解决方案 > NavigateByUrl 在使用 angular-oauth2-oidc 的 onTokenReceived 中不起作用

问题描述

我正在使用angular-oauth2-oidc包,我使用隐式流,并且(目前)无法迁移到代码流。

当流程结束时,我想导航到原始 url,我使用了文档建议的保留状态。

我的问题是我无法从函数导航,通过解决onTokenReceived的承诺解决但控制台上没有错误:navitageByUrlfalse

export class AppComponent {
    url: string;    

    constructor(
        private oauthService: OAuthService, 
        private router: Router) {

        this.url = window.location.pathname; // Get requested url.
    }

    ngOnInit() {        
        this.oauthService.loadDiscoveryDocument().then(res => {
            console.log(res);
            this.oauthService.tryLogin({
                onTokenReceived: (info) => {
                    // Receive state and navitage to.
                    this.router.navigateByUrl(info.state).then(res => {
                        if (!res) {
                            console.error("Navigate to " + info.state + " after get token:" + res);
                        }
                    });
                }
            }).then(res => {
                if (!res) { // If not login init implicit flow passing url as state.
                    this.oauthService.initImplicitFlow(this.url);                
                }

            })
        })        

    }
}

但是,如果使用以下命令在 100 毫秒后运行,它会起作用setTimeout

onTokenReceived: (info) => {
    // Receive state and navitage to.
    setTimeout(() => {
        this.router.navigateByUrl(info.state).then(res => {
            if (!res) {
                console.error("Navigate to " + info.state + " after get token:" + res);
            }
        });
    }, 100); // With less than 100 not works.
}

有人可以帮助我吗?为什么 navigateByUrl 不起作用?

标签: angularangular-oauth2-oidc

解决方案


我一直在调试角度路由器,以了解为什么导航解析为 false。我已经看到如果其他导航开始,导航可以取消。好吧,我已经记录了路由器事件,并且在我的导航过程中我可以看到其他导航开始了。

这是日志:

app.component.ts:31 NAVEvent- NavigationStart to /#id_token=eyJhbG(...hide for simplicity...)8da3798eac66
app.component.ts:31 NAVEvent- RoutesRecognized
app.component.ts:31 NAVEvent- GuardsCheckStart
app.component.ts:31 NAVEvent- ChildActivationStart
app.component.ts:31 NAVEvent- ActivationStart
app.component.ts:31 NAVEvent- GuardsCheckEnd
app.component.ts:31 NAVEvent- ResolveStart
app.component.ts:31 NAVEvent- ResolveEnd
app.component.ts:31 NAVEvent- ActivationEnd
app.component.ts:31 NAVEvent- ChildActivationEnd
app.component.ts:31 NAVEvent- NavigationEnd
app.component.ts:31 NAVEvent- Scroll
app.component.ts:50 TOKEN RECEIVED --> Here I received the token and init the navigation to original requested URL
app.component.ts:31 NAVEvent- NavigationStart to /data/orderByToken/f5c2a1af-b0fa-48ab-867d-d748f53d42fb
app.component.ts:31 NAVEvent- RouteConfigLoadStart
app.component.ts:31 NAVEvent- NavigationCancel   --> this cancel my navigation and causes false resolved.
app.component.ts:31 NAVEvent- NavigationStart to /welcome -> Angular navigate to /welcome due to I have a redirect on routing module.
app.component.ts:31 NAVEvent- RoutesRecognized
app.component.ts:31 NAVEvent- GuardsCheckStart
app.component.ts:31 NAVEvent- GuardsCheckEnd
app.component.ts:31 NAVEvent- ActivationEnd
app.component.ts:31 NAVEvent- ChildActivationEnd
app.component.ts:31 NAVEvent- NavigationEnd
app.component.ts:31 NAVEvent- Scroll

我在这样的角度路由配置中有一个重定向:

{ path:"", redirectTo: "welcome", pathMatch: "full"}{ path:"", redirectTo: "welcome", pathMatch: "full"}

不是 angular-oauth2-oidc 问题...

当导航承诺以 false 解决时,到 /welcome 的导航完成,因此我决定再试一次,再次运行导航,这一次有效。

就像是:

this.router.navigateByUrl(state).then(res => {
  if (!res) {
    this.router.navigateByUrl(state);
  }
});

因为如果导航失败会引发异常,只有当 promise 被解析为 false 时,无一例外,是由于另一个导航取消你的导航。

这解决了我的问题。


推荐阅读