2016-07-25 3 views
2

웹 응용 프로그램을 개발하기 시작했으며 프론트 엔드 프레임 워크로 Angular 2를 선택했습니다. 나는 현재 사용자 인증을 위해 Auth0을 시험 중이다. 문제는 다음과 같습니다. 방문 페이지 로그인 -> 리디렉션 기능을 구현하려고합니다. 웹 사이트를 열면 즉시 사용자의 토큰이 localStorage에 있는지 확인한 다음 로그인 위젯을 표시하거나 홈 페이지로 리디렉션해야합니다. 그러나 나는이 매우 불쾌한 버그에 부딪 쳤습니다.Auth0 및 Angular 2 : 로그인 위젯을 사용하여 로그인 및 라우팅에 실패했습니다.

내가 로그인 할 때 페이지가 새로 고침되고 위젯이 다시 나타납니다. 어떤 이유로 tokenNotExpired()false을 반환합니다. 같은 자격 증명으로 다시 로그인하려면 - 페이지 새로 고침, 로그인 위젯이 사라지고 로깅이 tokenNotExpired()이 (가) true을 반환하지만 아직 리디렉션이 작동하지 않는 것으로 나타납니다. 방금 기본 주소 인 http://localhost:4200을 입력하면 hometokenNotExpired()true으로 성공적으로 리디렉션합니다.

디버깅을 시도했지만 행운이 없었습니다. 어디에서 실패했는지 찾을 수 없었습니다.

본질적으로 나는 경험이 부족하기 때문에 리디렉션 기능을 코딩하는 방식에 문제가 있다는 것을 확신합니다. 어떤 도움을 주셔서 감사 드리며 잠시 앉아 계십니다.

중복 된 부분을 생략 한 코드를 발췌 한 내용이 포함되어 있습니다. main.ts에서 부트 스트랩 (bootstrapping)하여 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로 설정하면 문서에 다음 경고가있는 '팝업 모드'를 사용할 수 있습니다. iOS의 Android 또는 Firefox와 특정 상황에서 Internet Explorer의 팝업 모드가 제대로 작동하지 못하게하는 알려진 버그가 있습니다. 따라서 리디렉션 모드 만 사용하거나 이러한 특수한 경우를 감지하고 리디렉션 모드를 선택적으로 사용하는 것이 좋습니다. –