Angular2:canActivate将我重定向到登录页面,即使我已通过身份验证

时间:2017-03-23 11:22:56

标签: angular authentication angular2-routing

我正在使用angular2作为前端和弹簧/弹簧安全性作为后端的Web应用程序。

一切都运作良好,唯一的问题是,即使我已登录并且我想刷新成员视图,它也会将我重定向到登录页面。

AuthGuard服务

import { Injectable }     from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot }    from '@angular/router';
import {LoginService} from './login.service';

@Injectable()
export class AuthGuard implements CanActivate {

 constructor(private loginService: LoginService, private router: Router) {}


  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    let url: string = state.url;

    return this.checkLogin(url);
  }
   checkLogin(url: string): boolean {
    if (this.loginService.isAuthenticated) {  return true; }
      // Store the attempted URL for redirecting
    this.loginService.redirectUrl = url;
    // Navigate to the login page with extras
    this.router.navigate(['/login']);
    return false;
  }
}

login服务

import { Injectable } from '@angular/core';

import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/toPromise';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class LoginService {

  isAuthenticated: boolean = false;
// store the URL so we can redirect after logging in
  redirectUrl: string;

  constructor(private http: Http) {

  }

  login(username: string, password: string) {
    const headers = new Headers();
    const creds = 'username=' + username + '&password=' + password;

    headers.append('Authorization', 'Basic ' + btoa(username + ':' + password));
    headers.append('Content-Type', 'application/x-www-form-urlencoded');

    return new Promise((resolve) => {
      this.http.post('http://localhost:8080/webCustomerTracker/login', creds, { headers: headers })
      .map( this.extractData )
     .toPromise()//convert to promise
      .then(//use then instead of subscribe to form promise chain
          success => {
                     if(success) {
                window.localStorage.setItem('auth_key', success.data);
                this.isAuthenticated = true;
                    }
                resolve(this.isAuthenticated);
            });

    }
    );
  }
 logoutAPI(): Observable<any>{
        return this.http.get("http://localhost:8080/webCustomerTracker/logout")
                .map( (res: Response) => res.json() )
                .catch((error:any) => Observable.throw(error.json().error || ' Server Error '));
 }

   private extractData(res: Response) {
    let body;

    // check if empty, before call json
    if (res.text()) {
        body = res.json();
    }

    return body || {};
}
}

2 个答案:

答案 0 :(得分:1)

找到解决此问题的方法,我只是对 AuthGuard 服务中的 checkLogin 方法做了一点改动:

checkLogin(url: string): boolean {

    if (!!window.localStorage.getItem('auth_key')) {  return true; }
      // Store the attempted URL for redirecting
    this.loginService.redirectUrl = url;
    // Navigate to the login page with extras
    this.router.navigate(['/login']);
    return false;

  }

答案 1 :(得分:0)

这是因为在守卫中你正在制作一个新的AuthenticationService实例和

this.loginService.isAuthenticated

为空。尝试使用BehaviourSubject并订阅它以便能够获得值。

创建一个具有BehaviorSubject类型属性的类。例如:

@Injectable()
export class Globals {
    public loggedUser: BehaviorSubject<Account> = new BehaviorSubject<Account>(null);

在此变量中,您将在登录请求成功后立即存储已登录用户的信息。存储值的方式如下:

this.globals.loggedUser.next(--value-to-store--);// should be of type T

然后,为了从此对象获取值,请注入类并只需像

一样访问它
this.globals.loggedUser.getValue()

如果是!== null,那么您已经登录。