Angular2:canActivate

时间:2016-11-25 10:26:41

标签: authentication angular

目前我想实现canActivate功能,我想要的是每次请求页面时向服务器发送请求,并在json响应中获取true / false,以便了解用户身份验证并允许查看当前页面。 似乎我完全坚持使用可观察和承诺的对象,这对我来说是新的,到目前为止我是什么。

import { Injectable }     from '@angular/core';
import {CanActivate, Router}    from '@angular/router';
import { Http, Response } from '@angular/http';
import {Observable, Observer, Subject} from "rxjs/Rx";

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private router: Router, private http: Http) {}

    canActivate() {
        if (this.isAuthenticated()) {
            return true;
        } {
            this.router.navigate(['404']);
            return false;
        }
    }

    isAuthenticated() : Observable<boolean> {
        var subject = new Subject<boolean>();
        this.http.get("/index.php?module=Api&action=IsAuthenticated")
            .map((res : Response) => res.json())
            .subscribe(res => {
                console.log("next: returning true");
                subject.next(true);
            }, (res) => {
                console.log("next: returning false");
                subject.next(false);
            });
        return subject.asObservable().first();
    }
}

3 个答案:

答案 0 :(得分:2)

一些变化

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private router: Router, private http: Http) {}

    canActivate() {
        return this.isAuthenticated().first(); // not sure if `.first() is still necessary
    }

    isAuthenticated() : Observable<boolean> {
        return this.http.get("/index.php?module=Api&action=IsAuthenticated")
            .map((res : Response) => res.json())
            .catch(err => return Observable.of(false))
            .map(res => {
                return true
            });
    }
}

如果isAuthenticated()执行某些异步执行操作,我们无法返回truefalse,我们会收到Observable,但会发出true或最终false

我们所做的是返回我们从isAuthenticated()

获得的可观察量

isAuthenticated with return the observable we get from this.http.get()and transform the emitted event. It seems the response from the server ( res.json()) is not used. Therefore we use catch()to return false in case of an error and true`否则。

由于未使用服务器的响应.map((res : Response) => res.json())可能会被省略,除非您希望返回错误,因此应该返回错误false。 此外,您的生产代码可能看起来不同,需要处理响应。

我们不会在任何地方订阅,因为这是ObservablecanActivate返回时路由器正在执行的操作,如果我们调用subscribe(),我们会获得{{1}而不是Subscription

答案 1 :(得分:0)

canActivate可以返回Observable<boolean>Promise<boolean>boolean

由于您依赖于异步检查,因此无法返回布尔值。

然而,看起来你可以简单地做

canActivate(): Observable<boolean> {
  return this.isAuthenticated();
}

我还没有关于Observable的专家,但是如果您未经授权,也可以轻松链接重定向呼叫。

答案 2 :(得分:0)

以下是适合我的解决方案:

canActivate() {
    return this.http.get("/index.php?module=Api&action=IsAuthenticated")
        .toPromise()
        .then(this.extractData)
        .catch(this.handleError);
}