2017-06-05 19 views
1

私のWeb Angularプロジェクトでは、セキュリティを処理するためのAuthenticationGuardとAuthenticationServiceを作成しました。アングルサービスはその呼び出しごとにリセットされます

これらのファイルは、完璧に動作するプロジェクトの別のブランチからのものです。

  1. 移動し「認証/ログイン」へ
  2. ユーザーが自分の資格情報
  3. のAuthServiceがベアラートークン
  4. を取得するには、バックエンドwepApiを呼び出す入力:ここ

    は、どのように私のスクリプトべき作品でありますバックエンドはトークンを返します。

  5. AuthServiceは、彼のvarを 'isLoggedIn'に設定します。
  6. AuthServiceが '/ home'にナビゲートするためにルータに使用する
  7. AuthServiceは、AuthServiceの 'isLoggedIn'をチェックして認証を確認します。

私の問題は、AuthGuardがAuthServiceにアクセスするときです:AuthServiceは常にfalseを返します。私はあなたが行っていないと思われるあなたのモジュール定義を見なくても

auth.guard.ts

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

 
@Injectable() 
 
export class AuthGuard 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 { 
 
    if (this.authService.getIsLoggedIn()) { 
 
     return true; 
 
    } 
 

 
    // Store the attempted URL for redirecting 
 
    this.authService.redirectUrl = url; 
 

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

auth.service.ts

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

 
import { Observable } from 'rxjs/Observable'; 
 
import 'rxjs/add/observable/of'; 
 
import 'rxjs/add/operator/do'; 
 
import 'rxjs/add/operator/delay'; 
 

 
import { config } from './../shared/smartadmin.config'; 
 

 
import { Http, Headers, RequestOptions, Response } from '@angular/http'; 
 
import 'rxjs/add/operator/map' 
 

 
@Injectable() 
 
export class AuthService { 
 
    private isLoggedIn: boolean = false; 
 

 
    public redirectUrl: string; 
 

 
    constructor(private router: Router, private http: Http) { 
 
    } 
 

 
    public getIsLoggedIn(): boolean { 
 
     console.log("getIsLoggedIn() = " + this.isLoggedIn); // Always returns false 
 
     return this.isLoggedIn; 
 
    } 
 

 
    public login(username: string, password: string) { 
 
     this.ProcessLogin(username, password) 
 
      .subscribe(result => { 
 
       if (result === true) { 
 
        console.log("before attribution"); 
 
        console.log("this.isLoggedIn = " + this.isLoggedIn); // returns false 
 
        this.isLoggedIn = true; 
 
        console.log("after attribution"); 
 
        console.log("this.isLoggedIn = " + this.isLoggedIn); // returns true 
 
        this.router.navigate(this.redirectUrl ? [this.redirectUrl] : ['/home']); 
 
       } else { 
 
        this.logout(); 
 
       } 
 
      }); 
 
    } 
 

 

 
    public logout(): void { 
 
     localStorage.removeItem('oAuthToken'); 
 
     this.isLoggedIn = false; 
 
    } 
 

 
    private ProcessLogin(username: string, password: string): Observable<boolean> { 
 

 
     let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' }); 
 
     let options = new RequestOptions({ headers: headers }); 
 
     let body = 'grant_type=password&username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(password); 
 

 
     let endpoint = config.API_ENDPOINT + 'token'; 
 

 
     return this.http.post(endpoint, body, options) 
 
      .map((response: Response) => { 
 
       // login successful if there's a jwt token in the response 
 
       let token = response.json() && response.json().access_token; 
 
       if (token) { 
 
        localStorage.setItem('oAuthToken', token); 
 

 
        // return true to indicate successful login 
 
        return true; 
 
       } else { 
 
        localStorage.removeItem('oAuthToken'); 
 
        // return false to indicate failed login 
 
        return false; 
 
       } 
 
      }); 
 
    } 
 
}

+0

if elseロジックを購読部分に移動してもう一度やり直すことはできますか?マップの 'response.json()'を返すだけです。 – echonax

+0

すみませんが、私はあなたの提案を本当に理解していません。あなたは正確にそれを教えていただけますか? –

+0

'ProcessLogin'メソッドの中で' Observable 'を返すのではなく、あなたの' map'で 'response.json()'を返してください。あなたが 'login'メソッドの中で' ProcessLogin'に 'subscribe 'するときにif/elseロジックを行います。 – echonax

答えて

1

AuthServiceは、そのevを意味するコアサービス(シングルトン) eryモジュールは独自のインスタンスを持ちます(独自のisLoggedInフラグを追跡します)。

サービスを単一の角度にするには、ルートモジュールインジェクタがサービスを提供する必要があります。

import { NgModulep } from '@angular/core'; 
import { CommonModule, ModuleWithProviders } from '@angular/common'; 
import { AuthService, AuthGuard } from './services/index'; 

@NgModule({ 
    imports: [ 
    CommonModule, 
    ModuleWithProviders 
    ] 
}) 
export class SharedModule { 

    static forRoot(): ModuleWithProviders { 
    return { 
     ngModule: SharedModule, 
     providers: [ 
     AuthService, 
     AuthGuard 
     ] 
    }; 
    } 

} 

そしてルートAppModuleにSharedModuleをインポートするときにforRootメソッドを呼び出します。これを実現するために、あなたはこれを行う必要があります。

@NgModule({ 
    imports: [ 
    ... 
    SharedModule.forRoot(), 
    ... 
    ], 
    ..., 
    bootstrap: [AppComponent] 
}) 
export class AppModule { } 

+0

それはそのようにうまく動作します!ありがとう –

1

https://angular.io/docs/ts/latest/guide/ngmodule.html#!#core-for-rootは私が私の場合には、ボタン要素に配線されたクリックイベントによって引き起こされていた同様の問題を、持っていたが、ChromeでルックATTここで「設定コアサービス」を持っていますクロムのデフォルトアクションはボタンにタイプ属性がない場合、ボタンクリックをサブミットとして扱うため、ボタンがクリックされるたびにフォーム全体が送信されていました。

修正は HTMLでログインボタンにタグタイプ=「ボタン」を追加することであった

説明here

0

依存インジェクタの範囲内でシングルトンです。

しかし、Angular DIは階層注入システムであるため、入れ子式インジェクタが独自のサービスインスタンスを作成できることを意味します( )。 の詳細については、Hierarchical Injectorsを参照してください。
Source

ただ、ダブルチェックどこprovideあなたのサービス。

モジュールを一覧表示し、providersセクションをそれぞれ検査します。
複数のインスタンスがある場合、各モジュールは独自のサービスインスタンスを提供します。

私は同じ問題を抱えており、AuthServiceをAppModuleに追加し、AuthModuleから削除することを忘れてしまったので、ログインページ(authモジュール内)に他のインスタンスが含まれていました。

関連する問題