在Chrome中选择“在新标签页中打开链接”选项时,应用路由重定向到Angular App中的登录

时间:2017-09-28 17:17:53

标签: javascript angular typescript routing

我在Angular 2应用中发现了一个问题,我正在尝试进行故障排除。目前,当我点击整个应用中的链接时,我的路由按预期工作。以下是我的根路由文件中如何定义路由路径的示例:

{ path: 'home', component: HomeComponent, canActivate: [AuthGuard], data: {contentId: 'home-page'} },
{ path: 'contacts', component: ContactsComponent, canActivate: [AuthGuard], data: {contentId: 'contacts-page'} },

但是,如果在点击链接以路由到应用程序中的其他组件时,如果我也右键单击鼠标并选择“在新标签页中打开链接”,那么当新标签页打开时,会发生什么加载正确的组件,页面重定向到登录。同样,这只发生在我选择Chrome中的“在新标签页中打开链接”选项时。

我的登录组件的路径如下所示:

{ path: 'login', component: LoginComponent },

为了进一步说明,我在根路由文件中唯一的重定向逻辑是在无法识别路由时处理重定向到主组件:

{ path: '**', redirectTo: 'home' }

以下是“联系人”链接的示例 - 这是上面列出的路线之一: http://localhost:4200/contacts

这是默认的浏览器问题吗?这是一个默认的角度问题吗?只是想知道我如何跟踪这个问题。

顺便说一下,我认为这可能是一个AuthGuard问题,但即使我从“联系人”链接中删除了AuthGuard保护,当在新标签页中打开时,它仍然会重定向到登录组件。

以下是我的登录组件的样子:

    constructor(private router: Router,
                private route: ActivatedRoute,
                private authenticationService: AuthenticationService,
                private alertService: AlertService,
                private idle: Idle)
    {}

    ngOnInit()
    {
        // reset login status
        this.authenticationService.logout();

        // get return url from route parameters or default to '/'
        this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
    }

    login(response)
    {
        this.loading = true;
        this.authenticationService.login(this.model.username, this.model.password)
            .subscribe(
                data =>
                {
                    this.router.navigate(['/']);
                    this.reset();
                },
                error =>
                {
                    this.alertService.error(error, response);
                    this.loading = false;
                });
        this.authenticationService.username = this.model.username;
    }

    reset()
    {
        this.idle.watch();
        this.idleState = '';
        this.timedOut = false;
    }
}

此处调用的authenticationService的相关代码如下所示:

login(username: string, password: string)
{
    const u = encodeURIComponent(username);
    const p = encodeURIComponent(password);
    return this.http.post(this.url + this.ver + '/' + 'staff/login/' + u + '/' + p + '?' + this.key, {})
        .map((response: Response) =>
        {
            const user = response.json();
            if (user && (response.status = 200))
            {
                sessionStorage.setItem('currentUser', JSON.stringify(user));
                console.log('User ' + this.username + ' successfully authenticated with API');

                // Track active user id
                this._userId = user.data._id;

                // Trigger login change
                this.change.emit(this);
            } else
            {
                console.log('User ' + this.username + ' not recognized by API');
            }
        });
}

isAuthenticated()
{
    if (sessionStorage.getItem('currentUser'))
    {
        return true;
    } else
    {
        return false;
    }
}

logout()
{
    // remove user from local storage to log user out
    sessionStorage.removeItem('currentUser');
    console.log('User successfully logged out');

    // Reset active user
    this._userId = undefined;

    // Trigger event
    this.change.emit(this);

}

1 个答案:

答案 0 :(得分:2)

回答评论中的讨论:在您的AuthenticationService中,将sessionStorage更改为localStorage。 sessionStorage仅在选项卡的生命周期内持续存在。

参考:https://blog.guya.net/2015/06/12/sharing-sessionstorage-between-tabs-for-secure-multi-tab-authentication/