我有一个角度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
当用户未经过身份验证时,是否有更好的方法来拦截路由更改并重定向登录?
答案 0 :(得分:8)
对于任何发现这一点的人来说,现在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(实现并不重要),它可以告诉警卫用户是否已经过身份验证。如果有,则返回true,导航按常规进行。如果他们没有,我们返回false并将其重定向到登录屏幕。
答案 1 :(得分:2)
以下是使用带有Angular 2 RC6的AuthGuard的更新示例。
受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
答案 2 :(得分:0)
您也可以使用CanActivate
,但目前不支持直接DI。这是一个很好的workaround tho。