Ionic 2 - 从存储值获取令牌并在HTTP请求之前设置Header

时间:2016-12-08 08:49:13

标签: http angular ionic2 web-sql

我使用ionic/storage包在用户登录后存储api_token,这样我就可以使用唯一令牌与API进行交互。

我面临的问题是我需要通过storage.get获取值,该值会返回一个承诺并导致我想要设置的标题未及时设置。

我需要返回一个RequestOptions实例,但是无法弄清楚如何添加我从promise中检索到的头。添加与localStorage同步的头文件在测试时工作正常,因此问题必须是异步执行。

createAuthorizationHeader(headers: Headers) {
    // this does add the header in time
    localStorage.setItem('api_token', 'some token');
    headers.append('Authorization', 'Bearer ' + localStorage.getItem('api_token'));

    // this does not add the header in time
    return this.storage.get('api_token').then((value) => {
        headers.append('Authorization', 'Bearer ' + value);
    });
}

getHeaders(path): RequestOptions {
    let headers = new Headers({
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    });

    if(!this.isGuestRoute(path)) {
        this.createAuthorizationHeader(headers);
    }

    return new RequestOptions({ headers: headers });
}

get(path: string) {
    return this._http.get(this.actionUrl + path, this.getHeaders(path))
        .map(res => res.json())
        .catch(this.handleError);
}

编辑:工作代码现在看起来像这样

getApiToken(): Observable<Headers> {
    return Observable.fromPromise(this.storage.get('api_token'));
}

getHeaders(): Headers {
    return new Headers({
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    });
}

get(path: string) {
    let headers: Headers = this.getHeaders();

    if(!this.isGuestRoute(path)) {
        return this.getApiToken().flatMap(data => {
            headers.append('Authorization', 'Bearer' + data);

            return this._http.get(this.actionUrl + path, { headers : headers })
                .map(res =>  res.json())
                .catch(this.handleError);
        });
    }

    return this._http.get(this.actionUrl + path, { headers : headers })
        .map(res => res.json())
        .catch(this.handleError);
}

2 个答案:

答案 0 :(得分:9)

查看我的类似问题Angular2 - Use value of Observable returning method in another Observable

如果您将Promise转换为TVL_CD_LIST -------------------------------------------- I2510 K5900 Z6828 M1180 Z6827 ,则可以使用rxjs Observable函数。

让我告诉你一下你会看起来像什么

flatMap

或者(刚刚了解了这一点,所以不确定它是否会起作用)

getApiToken(): Observable<Headers> {
    return Observable.fromPromise(this.storage.get('api_token'));
   //OR return Observalbe.of(this.storage.get('api_token'));
}

getHeaders(): Headers { 
     //create all headers here except the 'api_token'
     .....
}


get(path: string): Observable<any> {
    let headers: Headers = this.getHeaders();
    return this.getApiToken().flatMap(data => {

       headers.append('Authorization', 'Bearer'+data);

       return this.http.get(this.actionUrl + path, headers)
          .map(res =>  res.json()) 
          .catch(this.handleError);
    });
}

答案 1 :(得分:0)

我建议查看拦截器:https://angular.io/guide/http(对于名为&#34的部分进行搜索;设置新的标题&#34;)。我尝试使用BaseRequestOptions但仍然会导致异步问题。

重新设置Ivaro18答案,将标题设置为接收到令牌并保存在存储中,当用户在终止应用/关闭浏览器后返回应用/页面时,会不会中断?标题在内存中设置,因此不会持久。