2016-12-30 50 views
7

我试图在我的应用程序中实现一个身份验证警卫。即;只有经过身份验证的用户才能访问我的应用的某些路由我遵循给予here的tut。如何让Angular2服务单例?

一旦用户登录,我将AuthService中的布尔值更改为true,以指示使用已登录。在应用程序的整个生命周期中需要保留哪些内容。

鉴于下面的源代码:

AUTH-guard.service.ts

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

@Injectable() 
export class AuthGuardService implements CanActivate { 
    constructor(private authService: AuthService, private router: Router) {} 
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {   
    let url: string = state.url; 
    return this.checkLogin(url); 
    } 

    checkLogin(url: string): boolean { 
    console.log('Auth Guard Service: ' + this.authService.isLoggedIn); 
    if (this.authService.isLoggedIn) { return true; } 
    // Store the attempted URL for redirecting 
    this.authService.redirectUrl = url; 

    // Navigate to the login page with extras 
    this.router.navigate(['/admin', 'admin-login']); 
    return false; 
    } 
} 

auth.service.ts

import { Injectable } from '@angular/core'; 
    import { Http } from '@angular/http'; 

    import { User } from '../user/shared/user.model'; 

    import { ServiceBase } from '../../core/service.base'; 
    import { appConfig } from '../../core/app.config'; 

    @Injectable() 
    export class AuthService extends ServiceBase { 
     public isLoggedIn: boolean = false; 
     redirectUrl: string; 
     apiUrl: string; 
     constructor(private http: Http) { 
      super(); 
      this.apiUrl = appConfig.apiBaseUrl + '/users/signin'; 
     } 
     signin(user: User, successCallback, errorCallback) { 
      return this.http.post(this.apiUrl, user).subscribe(
       res => { 
        this.isLoggedIn = true; 
        successCallback(res); 
       }, 
       err => { 
        //this.isLoggedIn = false; 
        errorCallback(err); 
       } 
      ); 
     }    
    } 

login.component.ts

import { Component, OnInit } from '@angular/core'; 
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; 
import { Router } from '@angular/router'; 
import { User } from '../../user/shared/user.model'; 
import { AuthService } from '../auth.service'; 

@Component({ 
    moduleId: module.id, 
    templateUrl: 'login.component.html' 
}) 
export class AdminLoginComponent implements OnInit{ 

    user: User; 
    userLoginForm: FormGroup; 

    constructor(
     private formBuilder: FormBuilder, 
     private authService: AuthService, 
     private router: Router){ 
     this.user = new User(); 
    } 

    ngOnInit(){ 
     this.buildLoginForm(); 
    } 
    buildLoginForm() { 
     ... 
    } 
    login() { 
     if(!this.userLoginForm.valid) return false; 
     this.authService.signin(this.user, 
      response => { 
       console.log('Login Component: ' + this.authService.isLoggedIn); 
       this.router.navigate(['/admin', 'products']); 
      }, 
      response => {} 
     ); 
    } 
} 

控制台输出

XHR finished loading: POST "http://localhost:3000/api/users/signin". 
login.component.ts:40 Login Component: true 
auth-guard.service.ts:23 Auth Guard Service: false 

编辑:app.module.ts

import { NgModule } from '@angular/core'; 
    ... 
    import { AuthGuardService } from './auth/auth-guard.service'; 
    import { AuthService } from './auth/auth.service'; 

    @NgModule({ 
     imports: [ 
      ... 
      AdminRoutingModule 
     ], 
     exports: [ 
     ], 
     declarations: [ 
      ... 
      AdminLoginComponent, 
      ... 
     ], 
     providers: [ 
      AuthGuardService, 
      AuthService, 
      ... 
     ], 
     bootstrap:[] 
    }) 
    export class AdminModule {} 

我在做什么错在这里?任何帮助,将不胜感激。

+2

见让你拥有所有的服务里面加上''你的modules'部分providers'服务单。如果你在组件的'providers'部分添加了服务,那么对于那个组件,新的服务实例将被初始化。 – ranakrunal9

+0

让我们在哪里添加此服务? App.module – Milad

回答

3

正如ranakrunal9所提到的,如果您在组件或指令中提供服务,则会为每个此类组件实例获得一个新实例。

您还将获得一个用于延迟加载模块的新实例(使用loadChildren加载)。延迟加载的模块获得它们自己的根作用域,并且如果在该延迟加载的模块中提供该服务,则此模块中的组件和服务将获得不同的服务实例。

为确保您的整个应用程序只有一个实例,请仅在AppModuleAppModule加载的模块中直接或间接使用imports: [...]提供。

https://stackoverflow.com/a/40981772/217408

+1

我在我的子模块(Admin Module)中提供了'AuthService'。正如你所建议的,我在'AppModule'中提供了'AuthService',现在一切正常。谢谢! –

+0

不客气。很高兴听到你能使它工作。 –