Angular 5通过身份验证保护所有视图

时间:2018-08-07 05:17:40

标签: angular angular5

我正在学习Angular5。我正在使用Azure ADAL对用户进行身份验证。

当路径为空时,我会将用户路由到登录页面。如果用户尚未登录,我们会提供一个登录按钮,单击该按钮会将用户带到Microsoft登录页面。下面是代码。

app-routing.module.ts

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

import { LoginComponent }      from './login/login.component';
import { HomeComponent }      from './home/home.component';

const routes: Routes = [
    { path: 'home', component: HomeComponent },
    { path: 'login', component: LoginComponent },
    { path: '', redirectTo: '/login', pathMatch: 'full' }
];

@NgModule({
    exports: [RouterModule],
    imports: [RouterModule.forRoot(routes)]
})
export class AppRoutingModule { }

login.component.ts

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

import { Adal5Service } from 'adal-angular5';

const config = {
    tenant: 'xxxxxxx',
    clientId: 'xxxxxx'
}

@Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

    constructor (private service: Adal5Service) {
        this.service.init(config);
    }

    ngOnInit() {
        this.service.handleWindowCallback();

        if (this.service.userInfo.authenticated) {
            window.location.href = "home";
        }
    }

    public isLoggedIn () {
        return this.service.userInfo.authenticated;
    }

    public login () {
        this.service.login();
    }

}

login.component.html

<input type="text" placeholder="CWOPA" class="cwopa-field" />
<button class="login-button" (click)='login()'>Login</button>

但是,当用户键入主屏幕URL时,即使用户未登录,屏幕也会打开。因此,我在login.component.ts中添加了isLoggedIn()方法,并且从主组件的init调用它方法。下面是代码

home.component.ts

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

import {LoginComponent} from '../login/login.component'

@Component({
    selector: 'app-home',
    templateUrl: './home.component.html',
    styleUrls: ['./home.component.css'],
    providers: [ LoginComponent ]
})
export class HomeComponent implements OnInit {

    private loginComponent: LoginComponent;

    constructor(loginComponent: LoginComponent) { 
        this.loginComponent = loginComponent;
    }

    ngOnInit() {

        if (!this.loginComponent.isLoggedIn()) {
            window.location.href = '/login';
        }
    }

}

在所有组件中都将重复同样的操作。

我的问题是,每当添加一个新组件时,如果未从组件的init方法中调用isLoggedIn方法,则该视图将不经身份验证显示。有没有一种更好的方法可以保护应用程序中的所有视图而不必在组件的init方法中编写代码?

1 个答案:

答案 0 :(得分:4)

使用Route Guards,这是一个示例:
路由:

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


import { MyProfileComponent } from './components/profile/my-profile/my-profile.component';

const appRoutes: Routes = [
    { path: '', redirectTo: 'home', pathMatch: 'full' },
    { path: 'profile/my-profile', component: MyProfileComponent, canActivate: [AuthGuardService] }
];

export const Routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

AuthGuardService:

import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { SessionStorageService } from 'ngx-webstorage';

@Injectable()
export class AuthGuardService implements CanActivate {

    constructor(public session: SessionStorageService, public router: Router) { }

    canActivate(): boolean {
        if (this.session.retrieve("login") == null) {
            this.router.navigate(['home']);
            return false;
        }
        return true;
    }

}

因此,除非经过身份验证,否则用户无法导航到个人资料/我的个人资料。