Angular + Node - 如何使用Auth Guard检查经过身份验证的用户

时间:2017-10-08 12:41:05

标签: angular typescript

我正在尝试通过向jwt标头提供对后端api的请求来检查using是否已经过Authenticated。如果是,则返回用户,否则将返回未授权。

我遇到的问题是auth.guard被触发并在console.log中返回undefined,因为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);
  }

}

这是实现这一目标的最佳实现吗?

1 个答案:

答案 0 :(得分:0)

您可以通过添加localstorage会话来简化此操作。用户通过身份验证后,您可以将令牌存储在localstorage中,在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;
}