2017-10-08 41 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

相关问题