2016-10-16 56 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