使用Angular2,如何在登录重定向

时间:2015-12-31 12:03:12

标签: redirect angular angular2-routing

使用Angular2创建单页应用程序,我会拦截未经身份验证的用户访问自定义RouterOutlet中的非公共路由并将其重定向到登录视图。成功登录后,我想将用户重定向到最初请求的视图,而不是默认视图。

我注意到Router有一个renavigate()函数导航到最后一条成功路线,但最后一条成功路线是/auth/login而不是最初请求的网址。

基本上:我如何访问或确定以前请求的网址?

除非我真的需要,否则我真的不想求助于传递查询字符串参数。理想情况下,history组件作为Router组件的一部分访问backbone.history集合会很好,类似于node app.js

4 个答案:

答案 0 :(得分:17)

  1. 使用Auth Guards(实现CanActivate)来防止未经身份验证的用户。请参阅official documentation示例和this blog
  2. 使用身份验证后卫中的RouterStateSnapshot来捕获请求的网址。

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
    {
        // keep the attempted URL for redirecting
        this._loginService.redirectUrl = state.url;
    }
    
  3. 使用Router成功进行身份验证时重定向到该网址(例如在login.component.ts中)。例如。 this._router.navigateByUrl(redirectUrl);

  4. P.S。 @MichaelOryl和@Vitali的建议可行,但我的方式更符合Angular2的最终版本。

答案 1 :(得分:6)

您可以在Location课程的docs中找到所需内容。 back()函数可能会为您完成。

另一种方法是订阅popstate中的Location个事件。 MDN has docs谈论你可能会收到的价值观。

class MyCLass {
  constructor(private location: Location) {
    location.subscribe((val) => {
        // do something with the state that's passed in
    })
  }
}

否则,您可能需要一种跟踪路由器中的更改的服务,以便您可以访问它们。

class MyTrackingService {
  constructor(private router: Router) {
    router.subscribe((val) => {
        // store the routes here so that you can peel them off as needed?
    })
  }
}

在这种情况下,我正在访问Router对象并订阅任何更改,以便我可以跟踪它们。

答案 2 :(得分:4)

这对我有用。将它注入主应用程序组件的构造函数中,该构造函数已在引导程序方法中注册它。 页面加载的第一个val应该是原始网址。 我之后取消订阅是为了提高效率,因为我不想(或许还有)想要收听此服务中的后续路由器事件。 将服务注入需要originalUrl的其他地方。

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';

@Injectable()
export class UrlTrackingService {

  public originalUrl: string;

  constructor(
    private router: Router
  ) {
    let subscription: Subscription = this.router.events.subscribe((val) => {
      this.originalUrl = val.url;
      subscription.unsubscribe();
    });
  }

}

答案 3 :(得分:3)

使用Angular 2.2.1更新了示例

将原始URL传递给登录组件的Auth Guard:

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private router: Router) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        if (localStorage.getItem('currentUser')) {
            // logged in so return true
            return true;
        }

        // not logged in so redirect to login page with the return url
        this.router.navigate(['/login', { returnUrl: state.url }]);
        return false;
    }
}

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';

import { AlertService, AuthenticationService } from '../_services/index';

@Component({
    moduleId: module.id,
    templateUrl: 'login.component.html'
})

登录后重定向到上一个/原始URL的登录组件:

export class LoginComponent implements OnInit {
    model: any = {};
    loading = false;
    returnUrl: string;

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

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

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

    login() {
        this.loading = true;
        this.authenticationService.login(this.model.username, this.model.password)
            .subscribe(
                data => {
                    // login successful so redirect to return url
                    this.router.navigate([this.returnUrl]);
                },
                error => {
                    // login failed so display error
                    this.alertService.error(error);
                    this.loading = false;
                });
    }
}

有关详细信息和工作演示,您可以查看this post