2017-10-08 81 views
0

我正在嘗試通過向存在jwt頭部的後端api請求進行身份驗證來檢查using。如果他們是用戶返回,如果沒有,它將返回未經授權的。Angular + Node - 如何使用Auth Guard檢查經過身份驗證的用戶

我遇到的問題是auth.guard被觸發並返回undefined在console.log中,因爲auth.service尚未完成查詢。

auth.guard.ts

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

@Injectable() 
export class AuthGuard implements CanActivate { 


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


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

    console.log(this.authService.isAuthenticated()); 

    if (this.authService.isAuthenticated()) { 
     return true; 
    } 

    this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } }); 
    return false 

    } 
} 

auth.service.ts

import { JwtService } from './jwt.service'; 
import { Injectable } from '@angular/core'; 
import { ApiService } from './api.service'; 
import { UserService } from './user.service'; 

@Injectable() 
export class AuthService { 

    user: any; 

    constructor(
    private apiService: ApiService, 
    private jwtService: JwtService, 
    private userService: UserService) { 


     this.getAuthenticatedUser().subscribe(res => { 
     console.log(res); 
     this.user = res; 
     }, (error) => { 
     this.user = null; 
     }); 


    } 

    login(credentials) { 

    let endpoint = 'auth/' 

    return this.apiService.post(endpoint, credentials) 
     .map(res => { 
     this.jwtService.saveToken(res.data.jwtToken); 
     window.localStorage.setItem('user_id', res.data.user._id); 
     }); 
    } 

    logout() { 

    } 


    isAuthenticated() { 
    return this.user; 
    } 

    getAuthenticatedUser() { 

    let endpoint = 'auth/' 

    return this.apiService.get(endpoint); 
    } 

} 

請告訴我是這裏最好的執行實現這一目標?

回答

0

您可以通過添加本地存儲會話來簡化此操作。用戶通過身份驗證後,可以將令牌存儲在本地存儲中,並且可以在authguard服務中檢查狀態。

例如:

如下您可以創建一個登錄用戶信息類,

export class LoginInfo { 
    username: string; 
    role: string; 
    token: string; 
    isLoggedIn: boolean; 
} 

,並在您authservice.ts

login(username: string, password: string): Observable<LoginInfo> { 
     const url = `${environment.apiUrl}/token`; 
     const params = 'username=' + username + '&password=' + password + '&grant_type=password'; 
     const headers = new Headers({ 
      'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' 
     }); 
     return this.http.post(url, params, { headers: headers, withCredentials: true }) 
      .map((response: Response) => { 
       console.log(response); 
       const token = response.json() && response.json().access_token; 
       if (token) { 
        this.tokenInfo = this.decodeToken(token); 
        this.loggedInfo = new LoginInfo(); 
        this.loggedInfo.role = this.tokenInfo.Role; 
        this.loggedInfo.token = token; 
        this.loggedInfo.username = username; 
        this.loggedInfo.isLoggedIn = true; 
        localStorage.setItem('token', token); 
        localStorage.setItem('loggedInfo', JSON.stringify(this.loggedInfo)); 
        return this.loggedInfo; 
       } else { 
        return this.loggedInfo; 
       } 
      }, 
      err => console.log(err)); 
    } 

,並在您auth-guard.service.ts

你可以簡單地檢查令牌和重定向到登錄,如果令牌不存在

canActivate() { 
    if (localStorage.getItem('loggedInfo')) { 
     return true; 
    } 
    this.router.navigate(['/login']); 
    return false; 
} 
+0

我的問題是,什麼阻止他人在localStorage的加入了手動loggedInfo項,將其設置爲任意值。 canActivate函數一旦找到該項目就會返回true。 – KHAN

+0

@KHAN你應該在這裏使用標記!你應該檢查這兩個令牌和isloggedin爲真 – Sajeetharan

+0

你是什麼意思,檢查兩者都是正確的?如果你的意思是檢查它們是否都在本地存儲中,那麼我仍然會遇到同樣的問題。本地項目的完整性可以改變/添加,所以我認爲我唯一的選擇是每次打電話給後端... – KHAN

相關問題