Angular2 auth guard无法正常工作

时间:2018-01-12 17:31:56

标签: angular typescript observable

我们要做的是保护身份验证路由,以确保只有未经过身份验证的用户才能访问,并且已验证的用户会自动重定向到仪表板。

检查某人是否经过身份验证:

  1. 检查localstorage中是否存在访问令牌,如果没有...他已通过身份验证

  2. 如果存在令牌,请检查php(服务器)是否有效

  3. 我试过以下

    在路线中

     {path: 'auth', loadChildren: 'app/auth/auth.module#AuthModule', canActivate: [UnAuthenticatedGuardService]},
    

    现在是UnAuthenticatedGuardService

    @Injectable()
     export class UnAuthenticatedGuardService implements CanActivate {
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|boolean {
    
        return new Observable(observer=>{
           this._authService.checkLoggedin().subscribe(
            (res) => {
             if(res){
                 this.router.navigate(['dashboard']);
                return false
              } 
                return observer.next(!res)
             },
           (err) => {
             return observer.next(false)
        })
      });
    
    }
    

    现在在authservice

    @Injectable()
     export class AuthService {
    
    
    checkLoggedin(): Observable<boolean> {    
     if(!this._accesstokenService.getToken('access_token')){
         return Observable.of(false); //just checks for localstorage
       }
    
     //if the access token exists takes it and checks if its a valid one on the server
     return this._httpclient.get(this.authurl + '/default/is-loggedin')
       .map((res) => {
          return res;
        }, (error) => {
          return Observable.of(false);
        }
      );
    

    }

    我在哪里出错,因为当令牌存在时上述操作失败并且没有处理服务器响应以检查是否存在访问令牌。 如果访问令牌已存在,则向服务器发出请求以检查其是否有效,但其响应是否永远不会传递给unauthenticatedguard

    我哪里错了?

2 个答案:

答案 0 :(得分:1)

哦,伙计哦。我可能是错的,但看起来你让它变得比它需要的复杂一点。我没有大量使用observables,但只是想知道:为什么不像res那样用Observable.of包裹所有其他项目?此外,response.code/default/is-loggedin的调用是什么,因为我非常确定任何2xx3xx代码都不会抛出您在请求中的错误。

以下是我如何实现防止经过身份验证的用户访问主页的相似功能,而不是重定向到信息中心:

main-auth-guard

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { UserService } from '../services/user.service'

@Injectable()
export class MainAuthGuard implements CanActivate {
  constructor(
    private user: UserService, 
    private router: Router
  ){}

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

      /**
       * If the currentUser exists, the user should be able to go to this page. If not, it should not be able to.
       */

      if ( state.url === "/") {
        if ( this.user.currentUser() ) {
          this.router.navigate(['/dashboard'])
          return false;
        } else if ( this.user.getLSToken()) {
          this.router.navigate(['/dashboard']);
          return false;
        }
      }

      return true;
  }
}

我的user.service(我删除了它的非相关部分)

@Injectable()
export class UserService {
  user:IClientUser;

  constructor(
    private http: HttpClient, 
    private router: Router
  ) {}

  /**
 * Get's the Local Storage token.
 */
  getLSToken() {
    return localStorage.getItem("token");
  }

  currentUser() {
    return this.user;
  }

 //...

答案 1 :(得分:1)

你已经过于复杂了,只需在你的警卫中做到这一点:

return this._authService.checkLoggedin().catch(loggedIn => { 
   this.router.navigate(['dashboard']);
   return Observable.of(false);
});

并进行身份验证检查,以便始终使用错误响应处理无效的身份验证:

checkLoggedin(): Observable<boolean> {    
 if(!this._accesstokenService.getToken('access_token')){
    return Observable.throw(false); //just checks for localstorage
 }

 //if the access token exists takes it and checks if its a valid one on the server
 return this._httpclient.get(this.authurl + '/default/is-loggedin')
   .map((res) => {
      return res;
    });
}