2016-10-16 90 views
0

我正在使用Angular2和Auth0進行身份驗證。我可以看到令牌正在存儲到本地存儲中。我在我的auth.service.ts文件中寫入一個函數來檢查一個有效的標記,然後在組件的init中調用該函數。我已經嘗試了這個功能的許多不同的變體,但不能讓應用程序正確驗證。重定向如果令牌無效

我登錄後,即使在登錄並檢索有效令牌時,它也會將我轉回主頁。

我的目標是不允許在沒有有效令牌的情況下訪問此頁面。但是,當有一個有效的令牌允許訪問此頁面。

這是我目前試過,

auth.service.ts

import { Injectable }      from '@angular/core'; 
import { Router, CanActivate }    from '@angular/router'; 
import { tokenNotExpired, JwtHelper }  from 'angular2-jwt'; 
import { myConfig }      from './auth.config'; 

// Avoid name not found warnings 
declare var Auth0Lock: any; 

var options = { 
    theme: { 
    logo: '../assets/img/logo.png', 
    primaryColor: '#779476' 
    }, 
    auth: { 
    responseType: 'token', 
    redirect: true, 
    redirectUrl: "http://localhost:3000/dashboard", 
    }, 
    languageDictionary: { 
    emailInputPlaceholder: "[email protected]", 
    title: "Login or SignUp" 
    }, 
}; 

@Injectable() 
export class Auth { 

    // Configure Auth0 
    lock = new Auth0Lock(myConfig.clientID, myConfig.domain, options,{}); 

    constructor(private router: Router) { 
    // Add callback for lock `authenticated` event 
    this.lock.on('authenticated', (authResult) => { 
     localStorage.setItem('jwtToken', authResult.idToken); 
    }); 
    } 

    public login() { 
    this.lock.show(); 
    }; 

    public authenticated() { 
    return tokenNotExpired(); 
    }; 

    public isAuthenticated(): boolean { 
    try { 
     var jwtHelper: JwtHelper = new JwtHelper(); 
     var token = this.accessToken; 
     if (jwtHelper.isTokenExpired(token)) 
      return false; 
     return true; 
    } 
    catch (err) { 
     return false; 
    } 
    } 

    private get accessToken(): string { 
     return localStorage.getItem('jwtToken'); 
    } 

    public logout() { 
    localStorage.removeItem('jwtToken'); 
    }; 
} 

guard.service.ts

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

@Injectable() 
export class Guard implements CanActivate { 

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

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean { 
     if (state.url !== '/pages/home' && !this.auth.isAuthenticated()) { 
      this.auth.logout(); 
      this.router.navigate(['/pages/home']); 
      return false; 
     } 
     return true; 
    } 
} 

app.routing.ts

import {Guard}       from "./services/guard.service"; 

const appRoutes: Routes = [ 
    { 
     path: '', 
     redirectTo: 'pages/home', 
     pathMatch: 'full', 
    }, 
    { 
     path: '', 
     component: FullLayoutComponent, 
     canActivate: [Guard], 
     data: { 
      title: 'Home' 
     }, 
     children: [ 
      { 
       path: 'dashboard', 
       component: DashboardComponent, 
       data: { 
        title: 'Dashboard' 
       } 
      }, 

app.module.ts

import { Guard }      from "./services/guard.service"; 
import { Auth }       from "./services/auth.service"; 

providers: [ 
    Guard, 
    Auth 
    ], 

回答

0

正確的方式來實現這一目標用逆天

import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; 
import { AuthService } from './authService'; 
import { Observable } from 'rxjs/Observable'; 

@Injectable() 
export class AuthGuard implements CanActivate { 

    constructor(protected router: Router, protected authService: AuthService) { 

    } 

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean { 

     if (state.url !== '/login' && !this.authService.isAuthenticated()) { 
      this.authService.logOut(); 
      this.router.navigate(['/login']); 
      return false; 
     } 

     return true; 
    } 
} 

而且在你rotes設置

path: 'admin', 
     component: AdminPages.AdminPagesComponent, 
     canActivate: [AuthGuard], 
     children: [ 
      { 
       path: 'dashboard', 
       component: Dashboard, 
       data: { 
        menu: { 
         title: 'Dashboard', 
         icon: 'ion-android-home', 
         selected: false, 
         expanded: false, 
         order: 0 
        } 
       } 
      }, 

authservice

public isAuthenticated(): boolean { 
    try { 
     var jwtHelper: JwtHelper = new JwtHelper(); 
     var token = this.accessToken; 
     if (jwtHelper.isTokenExpired(token)) 
      return false; 
     return true; 
    } 
    catch (err) { 
     return false; 
    } 
} 

public logOut(): void { 
    localStorage.removeItem("access_token"); 
} 

private get accessToken(): string { 
     return localStorage.getItem('access_token'); 
    } 



private saveJwt(jwt): void { 
     if (jwt) { 
      localStorage.setItem('access_token', jwt) 
     }   
    } 
    public login(loginModel: LoginModel): Promise<void> { 
     return new Promise<void>((resolve, reject) => { 
      var username = loginModel.email; 
      var password = loginModel.password; 
      var creds = 
       "username=" + username + "&password=" + password + "&client_id=" + this.clientId + "&grant_type=" + this.grant_type; 
      var headers = new Headers(); 
      headers.append('Content-Type', 'application/x-www-form-urlencoded'); 
      this.httpClient.post(this.identityServerUrl + "/connect/token", creds, { headers }) 
       .toPromise() 
       .then(response => { 
        this.saveJwt(response.json().access_token); 
        resolve(); 
       }) 
       .catch(err => { 
        reject(err.json().error_description) 
       }); 
     }); 
    } 
+0

我感謝你的幫助。我正試圖通過這一點來了解發生了什麼。我假設一旦我把它放在正確的地方,我需要導入一些東西,是this.accessToken一個內置對象auth0? – wuno

+0

@wuno在當前的例子我用jwtHelper的angular2-jwt,你能提供哪些庫用於tokenNotExpired函數嗎? –

+0

我從'angular2-jwt'使用這一個import {tokenNotExpired};在我的auth.service.ts – wuno