2017-06-14 1 views
0

ログイン後にリダイレクトされるリンクを作成しようとしています(/ signinルート)/ダッシュボード/概要の子ルート運がない。私はリンクをクリックすると、エラーも応答も出ません。正しいブラウザの下部バーにパスが表示されます.URLを手動で入力すると正しいページにアクセスすると、ルートは/ダッシュボード/概要になります。何かする必要があるかどうかわからないことの1つは、ルートがAuthGuardedであるということです。角4、ルータ4.0.0:ルータリンクまたはrouter.navigateがプログラムによって子ルートにリダイレクトされない

私はリダイレクトサインインした後、プログラムでダッシュボードにユーザーを両方を試してみました、私もクロームコンソールrouterLinkを作成

onSignin(form: NgForm){ 
    const email = form.value.email; 
    const password = form.value.password; 
    this.user = {email, password}; 
    this.authServiceSubscription = this.authService.signinUser(this.user).subscribe(
     (response) => { 
     //redirect to dashboard 
     const loginResultCode = response.login_result_code; 
     if (loginResultCode == "SUCCESS") { 
         console.log("Sponsor logged in"); 
         this.authService.changeStatusToAuthenticated(); 
         //redirect to dashboard 
         console.log('Redirecting to dashboard'); 
         this.router.navigate(['/dashboard/overview']); 
        } else { 
         console.log("There were errors with the data"); 
         //present errors to the user 
         this.errorMessage = "Los datos de autenticación son incorrectos. Intente nuevamente"; 
        } 
     }, 
     (error) => { console.log("Error Login", error); this.errorMessage = "Hubo un error interno, intente de nuevo mas tarde";} 
     ); 
    } 

も上の「ダッシュボードにリダイレクトする」というメッセージを見ることができますが、そうでありませんコンソールのいずれかで動作し、何も起こらない、いなくてもエラー:

const appRoutes: Routes = [ 
    { path: '', redirectTo: '/', pathMatch:'full'}, 
    { path: '', component: MainComponent }, 
    { path: 'signin', component:SigninComponent}, 
    { path: 'signup', component: SignupComponent}, 
    { path: 'dashboard', canActivate:[AuthGuard],component: DashboardComponent, 
    children: [ 
     { path: '', redirectTo:'/dashboard/overview', pathMatch: 'full'}, 
     { path: 'overview', component: OverviewCampaignsComponent }, 
     { path: 'active', component: ActiveCampaignsComponent}, 
     { path: 'history', component: HistoryCampaignsComponent} 
    ] }, 
    { path: 'not-found', component: ErrorPageComponent }, 
    { path: '**', redirectTo: '/not-found' } 

] 

<li><a style="cursor: pointer;" routerLink="/dashboard/overview">Go To Dashboard</a></li> 

ここに私のルーティングファイルがあります

DashboardコンポーネントのngOnInitにconsole.logを配置してコンポーネントが作成されるか、概要コンポーネントで表示されるかはわかりませんが、運がないため、プログラムでナビゲートするとコンソール上にメッセージが表示されませんrouterLinkとは関係ありません。私は上記のように手動でアクセスしたときにメッセージを受け取りました。何か案は?ありがとうございました

EDIT:私はダッシュボードのルートに適用しています、これはAuthGuardファイルです。何らかのエラーをキャッチしていない可能性があります。それは??すべきである:のAuthServiceに

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


@Injectable() 
export class AuthGuard implements CanActivate { 

    constructor(private authService: AuthService, private router: Router) { } 

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { 
    return this.authService.isAuthenticated().map(isAuth => { 
     if (isAuth){ 
     console.log("Auth Guard approves the access"); 
     return true; 
     } 
     else { 
     console.log('AuthGuard Denying route, redirecting to signin'); 
     this.router.navigate(['/signin']); 
     return false; 
     } 
    }); 
    } 
} 

にisAuthenticated()メソッドは、単にユーザの認証状態で観察を返します。私は競合状態か何かがあるのだろうか...最初にhttp非同期要求を行うことによって観測値が設定されるようにする... isAuthenticatedメソッドにconsole.logを置くとコンソールに記録される。 authguard機能のマップ内にconsole.logを入れて、コードが実行されていない何らかの理由でログに記録されない場合....

auth.service.ts

import { Injectable, OnInit } from '@angular/core'; 
    import { Router } from '@angular/router'; 
    import { Http, Response, RequestOptions, Headers } from '@angular/http'; 
    import 'rxjs/add/operator/map'; 
    import {Observable, Subject} from "rxjs/Rx"; 

    @Injectable() 
    export class AuthService implements OnInit { 
    userIsAuthenticated = new Subject(); 
     constructor(private router: Router, private http: Http) { 
     this.ngOnInit(); 
     } 

     private getHeaders(){ 
      let headers = new Headers(); 
      headers.append('Content-Type', 'application/json'); 
      headers.append('Accept', 'application/json'); 
      headers.append('Authorization','Bearer'); 
      return headers; 
     } 

     ngOnInit(){ 

     this.changeStatusToUnauthenticated(); 
     //initial check with the server 
     let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true }); 

     this.http.get('http://localhost:3000/api/sponsor/check/login',options) 
      .map(response => { 
     console.log("Execute this"); 
      if (response.status === 200) { 
       console.log("execute also this"); 
       this.changeStatusToAuthenticated(); 
       return Observable.of(true); 
      } 
      } 
     ).catch((err)=>{ 
      //maybe add in the future if the code is 403 then send him to login otherwise send him elsewhere 
      if(err.status === 403){ 
      console.log('Forbidden 403'); 
    //  If I want to redirect the user uncomment this line 
    //  this.router.navigate(['/signin']); 
      } 
      this.changeStatusToUnauthenticated(); 
      return Observable.of(false); 
     }).subscribe((isAuth)=>{ 
      console.log("Initial refresh auth state ", isAuth); 
     }); 

     } 

     isAuthenticated(): Observable<boolean> { 
    if(this.userIsAuthenticated){ 
//if I change this line for return Observable.of(true) it works 
    return this.userIsAuthenticated; 
}else{ 
    return Observable.of(false); 
} 
    } 

     logout() { 
     console.log('logging out'); 
     let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true }); 
     return this.http.get('http://localhost:3000/api/sponsor/logout/', options).map(res=>res.json()) 
     .subscribe(
      (response) => { 
       //redirect to dashboard 
      const logoutResultCode = response.code; 
       if (logoutResultCode == "200") { 
          console.log("Sponsor logged out successfully"); 
          //redirect to dashboard 
          this.changeStatusToUnauthenticated(); 
          this.router.navigate(['/signin']); 
         } 
      }, 
      (error) => { 
       console.log("Error Logout- Header", error); 
       //check for 403 if it's forbidden or a connection error 
       this.changeStatusToUnauthenticated(); 
       this.router.navigate(['/signin']);} 
     ); 

     } 

     signinUser(user) { 
     console.log("Logging user"); 
     let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true }); 
     return this.http.post('http://localhost:3000/api/sponsor/login/', user, options).map(
      response => response.json()); 
     } 

     registerUser(user) { 
     let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true }); 
     return this.http.post('http://localhost:3000/api/sponsor/register/', user, options).map(
      response => response.json()); 
     } 

     changeStatusToUnauthenticated(){ 
     this.userIsAuthenticated.next(false); 
     } 

     changeStatusToAuthenticated(){ 
     this.userIsAuthenticated.next(true); 
     } 


    } 

EDIT 2:私はそれは私が時々あるあなたが購読していた中で、通常の対象に比較してかなりクールな機能です最後の放出された値を取得することができます原因代わりのAuthServiceの件名の行動件名を使用十分ではない。私の答えは以下の通りです。

+0

ファイルルータイベントは '[RouterModule.forRoot(routes、{enableTracing:true})]で有効にできます。 –

+0

ルータの出口は2つありますか? 1つは親のためのものと、もう1つは子供のルートのためのものです。私はそれが役立つ場合は、ここに広範なルーティングとサンプルアプリケーションがあります:https://github.com/DeborahK/Angular-Routing – DeborahK

+0

私は、ダッシュボードコンポーネント上で、私は子コンポーネントをレンダリングする別のルータのアウトレットがあります....それは問題と関係がありますか? – Juan

答えて

1

最後にisAuthenticated()メソッドで返されたauthServiceの問題は、ログに基づいて解決された値を返していなかったため、authguardはコンポーネントへのルートを解決する前に突っ込まれていました。 rxjsのドキュメントを検索して私の質問を解決しました。私はBehaviorSubjectを見つけたhttps://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md

これは、私がObservable.of(userIsAuthenticated.getValue())を返すことができるように、最後の値を取得し、それをAuthGuardに渡すことができるようになりました。最後に出力された値がfalseだった場合、ユーザーをログイン画面に送信するかどうかを決定するためのダミー要求を行うというロジックを追加しました。これは、私がサーバーに行うすべての要求に対してhttp禁止応答を受け取った場合、BehaviourSubjectの値をfalseに変更することと引き合いに出ます。これを組み合わせることで、フロントエンドとバックエンドの従来のセッション間の一貫性を保証し、バックエンドで期限切れのセッションとフロントエンドで期限切れでないセッションを回避します。これが誰かを助けることを望みます。コード:

auth.service.ts

 @Injectable() 
     export class AuthService implements OnInit { 
     userIsAuthenticated= new BehaviorSubject(null); 
      constructor(private router: Router, private http: Http) { 
      this.ngOnInit(); 
      } 

      private getHeaders(){ 
       let headers = new Headers(); 
       headers.append('Content-Type', 'application/json'); 
       headers.append('Accept', 'application/json'); 
       headers.append('Authorization','Bearer'); 
       return headers; 
      } 


     ngOnInit() { 
     //initial check with the server 
     this.doAuthCheck(); 

     } 

     doAuthCheck(): Observable<boolean> { 

     let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true }); 

     return this.http.get('http://localhost:3000/api/check/login', options) 
      .map(response => { 
      if (response.status === 200) { 
       this.changeStatusToAuthenticated(); 
       return Observable.of(true); 
      } 
      } 
     ).catch((err) => { 
      //maybe add in the future if the code is 403 then send him to login otherwise send him elsewhere 
      if (err.status === 403) { 
       console.log('Forbidden 403'); 
       //  If I want to redirect the user uncomment this line 
       //  this.router.navigate(['/signin']); 
      } 
      this.changeStatusToUnauthenticated(); 
      return Observable.of(false); 
      }); 
     } 

     isAuthenticated(): Observable<boolean> { 
     const isAuth = this.userIsAuthenticated.getValue(); 
     if (isAuth) { 
      return Observable.of(isAuth); 
     } else { 
      return this.doAuthCheck(); 
     } 
     } 


    logout() { 
    console.log('logging out'); 
    let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true }); 
    return this.http.get('http://localhost:3000/api/logout/', options).map(res => res.json()) 
     .subscribe(
     (response) => { 
     //redirect to dashboard 
     const logoutResultCode = response.code; 
     if (logoutResultCode == "200") { 
      console.log("logged out successfully"); 
      //redirect to dashboard 
      this.changeStatusToUnauthenticated(); 
      this.router.navigate(['/signin']); 
     } 
     }, 
     (error) => { 
     console.log("Error Logout- Header", error); 
     //check for 403 if it's forbidden or a connection error 
     this.changeStatusToUnauthenticated(); 
     this.router.navigate(['/signin']); 
     } 
    ); 

    } 



    signinUser(user) { 
    console.log("Logging user"); 
    let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true }); 
    return this.http.post('http://localhost:3000/api/login/', user, options).map(
     response => response.json()); 
    } 

    registerUser(user) { 
    let options = new RequestOptions({ headers: this.getHeaders(), withCredentials: true }); 
    return this.http.post('http://localhost:3000/api/register/', user, options).map(
     response => response.json()); 
    } 

changeStatusToUnauthenticated() { 
    this.userIsAuthenticated.next(false); 
    } 

    changeStatusToAuthenticated() { 
    this.userIsAuthenticated.next(true); 
    } 

     } 

AUTH-guard.service.ts

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


@Injectable() 
export class AuthGuard implements CanActivate { 

    constructor(private authService: AuthService, private router: Router) { } 

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { 
    return this.authService.isAuthenticated().map(isAuth => { 
     console.log("is Authenticated",isAuth); 
     if (isAuth){ 
     console.log("Auth Guard approves the access"); 
     return true; 
     } 
     else { 
     console.log('AuthGuard Denying route, redirecting to signin'); 
     this.router.navigate(['/signin']); 
     return false; 
     } 
    }); 
    } 
} 

ルートルータイベントをイネーブル

const appRoutes: Routes = [ 
    { path: '', redirectTo: '/', pathMatch:'full'}, 
    { path: '', component: MainComponent }, 
    { path: 'signin', component:SigninComponent}, 
    { path: 'signup', component: SignupComponent}, 
    { path: 'dashboard', canActivate:[AuthGuard],component: DashboardComponent, 
    children: [ 
     { path: '', redirectTo:'/dashboard/overview', pathMatch: 'full'}, 
     { path: 'overview', component: OverviewCampaignsComponent }, 
     { path: 'active', component: ActiveCampaignsComponent}, 
     { path: 'history', component: HistoryCampaignsComponent} 
    ] }, 
    { path: 'not-found', component: ErrorPageComponent }, 
    { path: '**', redirectTo: '/not-found' } 

] 
関連する問題