Angular 2 子路由认证

Angular 2 Authentication with child routes

我有一个 angular 2 应用程序,我需要在其中的每个页面上进行身份验证。所以我实现了一个自定义 RouterOutlet 来确认我在每次页面更改时都已登录。

@Directive({
   selector: 'auth-outlet'
})
export class AuthOutlet extends RouterOutlet {
   publicRoutes: any;
   private parentRouter: Router;
   private authService: AuthService;
   constructor(_elementRef: ElementRef, 
               _loader: DynamicComponentLoader, 
               _parentRouter: Router,
               @Attribute('name') nameAttr: string, 
               _authService: AuthService) {

      super(_elementRef, _loader, _parentRouter, nameAttr);
      this.parentRouter = _parentRouter;
      this.authService = _authService;
      this.publicRoutes = {
          'Login': true
      };
  }

  activate(oldInstruction: ComponentInstruction) {
      var url = this.parentRouter.lastNavigationAttempt;
      console.log('attemping to nav');
      if (!this.publicRoutes[url] && !this.authService.loggedIn){
          var newInstruction = new ComponentInstruction('Login', [], new RouteData(), Login, false, 1);
          return super.activate(newInstruction);
      } else {
          return super.activate(oldInstruction);
      }
   }
}

这是一个工作代码: http://plnkr.co/edit/YnQv7Mh9Lxc0l0dgAo7B?p=preview

有没有更好的方法在用户未通过身份验证时拦截路由更改并重定向登录?

您也可以使用 CanActivate, however direct DI is not supported at the moment. Here is a nice workaround

祝你好运。

对于发现此问题的任何人,现在 Angular 2 中的答案是使用 "Guards" 作为新路由器的一部分。请参阅 Angular 2 个文档:

https://angular.io/docs/ts/latest/guide/router.html#!#guards

基本守卫只是实现 "CanActivate",并且可以按如下方式工作:

import {Injectable} from "@angular/core";
import {CanActivate, Router} from "@angular/router";
import {AuthService} from "../services/auth.service";

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private authService:AuthService, private router:Router){}

    canActivate(){
        if(this.authService.isAuthenticated())
            return true;

        this.router.navigate(["/login"]);
        return false;
    }
}

正如您在本示例中所见,我在其他地方有一个 AuthService 运行(实现并不重要),它可以告诉守卫用户是否已通过身份验证。如果他们有,return true 并且导航照常进行。如果他们还没有,我们 return false 并将他们重定向到登录屏幕。

这是一个使用 AuthGuard 和 Angular 2 RC6 的更新示例。

主路由受 AuthGuard 保护的路由

import { Routes, RouterModule } from '@angular/router';

import { LoginComponent } from './login/index';
import { HomeComponent } from './home/index';
import { AuthGuard } from './_guards/index';

const appRoutes: Routes = [
    { path: 'login', component: LoginComponent },

    // home route protected by auth guard
    { path: '', component: HomeComponent, canActivate: [AuthGuard] },

    // otherwise redirect to home
    { path: '**', redirectTo: '' }
];

export const routing = RouterModule.forRoot(appRoutes);

如果用户未登录,AuthGuard 将重定向到登录页面

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

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private router: Router) { }

    canActivate() {
        if (localStorage.getItem('currentUser')) {
            // logged in so return true
            return true;
        }

        // not logged in so redirect to login page
        this.router.navigate(['/login']);
        return false;
    }
}

有关完整示例和工作演示,您可以查看 this post