2016-07-25 12 views
2

Webアプリケーションの開発を開始し、フロントエンドフレームワークとしてAngular 2を選択しました。私は現在、ユーザー認証のためにAuth0を試しています。 問題は次のとおりです。 ランディングページのログイン - >リダイレクト機能を実装しようとしています。ウェブサイトを開いた直後に、ユーザーのトークンがlocalStorageにあるかどうかを確認して、ログインウィジェットを表示するか、ホームページにリダイレクトするかのいずれかを選択する必要があります。しかし、私はこの非常に厄介なバグに遭遇しました:Auth0とAngular 2:ログインウィジェットを使用したログインとルーティングに失敗しました

私がログインすると、ページがリフレッシュされ、再びウィジェットが表示されます。何らかの理由でtokenNotExpired()falseを返します。同じ資格情報で再度ログインするには - ページが更新され、ログインウィジェットが消え、ログにtokenNotExpired()が返ってきて、今度はtrueが返されますが、私のリダイレクトはまだ動作しません。私が今自分のベースアドレスhttp://localhost:4200を入力するだけで、私はhomeに首尾よくリダイレ​​クトされ、tokenNotExpired()trueを返します。

私はそれをデバッグしようとしましたが、何の不運もありません - どこが失敗しているのかわかりません。

私の経験が不足しているので、私はリダイレクト機能をコーディングする方法には基本的に問題があると確信しています。私は非常に親切に助けを感謝し、これにしばらく座っている。

私は冗長部分を省略したコードの抜粋を含めています。 main.tsにブートストラップすることでAuthサービスをグローバルに注入しています。

app.routes.ts:

import {provideRouter, RouterConfig} from "@angular/router"; 
import {AuthGuard} from './secure/auth.guard'; 
import {AdminGuard} from "./secure/admin.guard"; 

import {UserHomeComponent} from "./main/user-cpl/user-home.component"; 
import {AdminHomeComponent} from "./main/admin-cpl/admin-home.component"; 
import {LoginPageComponent} from "./login/login-page.component"; 

const APP_ROUTES: RouterConfig = [ 

    { path: 'home', canActivate: [AuthGuard], 
    children: [ 
     { path: '', component: UserHomeComponent }, 
     { path: 'admin', component: AdminHomeComponent, canActivate: [AdminGuard] }, 
     ] }, 
    { path: 'login', component: LoginPageComponent }, 
    { path: '', redirectTo: 'home', pathMatch: 'full' }, 
    { path: '**', redirectTo: 'home', pathMatch: 'full' } 
]; 

export const APP_ROUTES_PROVIDER = [ 
    provideRouter(APP_ROUTES) 
]; 

ログイン-page.component.ts:

import {Component, OnInit} from '@angular/core'; 
import {ROUTER_DIRECTIVES, Router} from '@angular/router'; 
import {Auth} from '../secure/auth.service'; 

@Component({ 
    moduleId: module.id, 
    selector: 'login-page-component', 
    template: ` 
    <router-outlet></router-outlet> 
    `, 
    directives: [ROUTER_DIRECTIVES] 
}) 
export class LoginPageComponent implements OnInit { 

    constructor(private auth: Auth, private router: Router) { 
    } 

    ngOnInit():any { 
    console.log('LOGGED IN - ' + this.auth.loggedIn()); 
    if (this.auth.loggedIn()) { 
     if (this.auth.isAdmin()) { 
     this.router.navigate(['/home/admin']); 
     } else if (!this.auth.isAdmin()) { 
     this.router.navigate(['/home']); 
     } 

    } else { 
     this.auth.login(); 
    } 
    } 
} 

auth.service.ts:

import {Injectable} from '@angular/core'; 
import {tokenNotExpired} from 'angular2-jwt'; 

declare var Auth0Lock: any; 

@Injectable() 
export class Auth { 
    // Configure Auth0 
    lock = new Auth0Lock('omitted', 'omitted', { 
    closable: false 
    }); 

    //Store profile object in auth class 
    userProfile: any; 

    constructor() { 
    // Set userProfile attribute if already saved profile 
    this.userProfile = JSON.parse(localStorage.getItem('profile')); 

    // Add callback for lock `authenticated` event 
    this.lock.on("authenticated", (authResult) => { 
     localStorage.setItem('id_token', authResult.idToken); 

     // Fetch profile information 
     this.lock.getProfile(authResult.idToken, (error, profile) => { 
     if (error) { 
      // Handle error 
      alert(error); 
      return; 
     } 

     localStorage.setItem('profile', JSON.stringify(profile)); 
     this.userProfile = profile; 
     }); 
    }); 
    } 

    login() { 
    this.lock.show({ 
     callbackUrl: 'http://localhost:4200/home' 
    }); 
    } 

    logout() { 
    localStorage.removeItem('profile'); 
    localStorage.removeItem('id_token'); 
    this.userProfile = undefined; 
    } 

    loggedIn() { 
    return tokenNotExpired(); 
    } 

    isAdmin() { 
    return this.userProfile && this.userProfile.app_metadata 
     && this.userProfile.app_metadata.roles 
     && this.userProfile.app_metadata.roles.indexOf('admin') > -1; 
    } 
} 

auth.guard.ts:

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

@Injectable() 
export class AuthGuard implements CanActivate { 

    constructor(private auth: Auth, private router: Router) { 
    } 

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) { 
    if (this.auth.loggedIn()) { 
     console.log('AUTH GUARD PASSED'); 
     return true; 
    } else { 
     console.log('BLOCKED BY AUTH GUARD'); 
     this.router.navigate(['/login']); 
     return false; 
    } 
    } 
} 

admin.guard.ts:それは、単一のページのアプリですので、あなたが設定でredirect: falseを設定する必要があります

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

@Injectable() 
export class AdminGuard implements CanActivate { 

    constructor(private auth: Auth, private router: Router) {} 

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) { 
    if (this.auth.isAdmin()) { 
     return true; 
    } else { 
     return false; 
    } 
    } 
} 
+0

'auth.login()であなたの属性は' callbackURL'でなければなりません。 OAuthでは大文字と小文字が区別されます。 – ghg565

+0

@ ghg565はい、私はそれを変更しましたが、影響はありません。また、どこでもリダイレクトするためにcallbackURLを使用せず、代わりにログインページに戻り、最初に資格情報を保存しないことに気付きました。 – praktikantas

答えて

4

。 Auth0はそれ以外の場合はredirectUrlへのGETコールを行います。この呼び出しにより、authenticatedイベントが発生しなくなりました。このように、あなたのauth.service.tsファイルに:

lock = new Auth0Lock('omitted', 'omitted', { 
    closable: false, 
    auth: { // <--- mind this nesting 
    redirect: false 
    } 
}); 

これは、ログイン時にサービスの「認証済み」イベントを呼び出します。ログインが完了したら、ユーザーをリダイレクトしたいと思うかもしれません。したがって、コールバックでthis._router.navigate(['path'])を呼び出します。 import { Router } from 'angular/router'を忘れずに、コンストラクタにインスタンスを作成してください:constructor(private _router: Router) {}

+0

リダイレクトをfalseに設定すると、「ポップアップモード」が有効になります。このモードでは、次の警告がドキュメントに表示されます。ポップアップモードがAndroidやFirefoxのiOSやInternet Explorerで正常に機能しないような既知のバグがあります。したがって、リダイレクトモードを使用するか、これらの特殊なケースを検出し、リダイレクトモードを選択的に有効にすることをお勧めします。 –

関連する問題