use*_*svm 7 ionic2 ionic3 angular
在下面的代码中,我发布了两个代码在控制台中返回的示例.对于拦截器,我应该返回一个可观察的.我已将本地存储承诺转换为使用switchmap的可观察对象.我仍然使用这种方法返回null.我的observable包含在函数中,所以我应该得到一个null以外的值.谢谢!
Interceptor.js
import { fromPromise } from 'rxjs/observable/fromPromise';
accessToken: string;
emptyToken: any;
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
//example
this.storage.get('token').then((val) => {
this.accessToken = val
return console.log(this.accessToken, ' this is returning null value for token')
})
//trying to return actual header
return fromPromise(this.storage.get('token')).switchMap(access => {
this.accessToken = access
console.log(this.accessToken, ' this is returning null value for token')
const authReq = req.clone({
setHeaders: {
Authorization: this.accessToken
}
});
return next.handle(authReq)
})
}
}
Run Code Online (Sandbox Code Playgroud)
我已经添加了下面更新的代码,请忽略上面的代码并仍然得到相同的结果.作为下面所述的答案之一,它们在所有假设中都是正确的.归结为将令牌置于登录observable内部.问题不在于拦截器,代码工作正常.我需要以某种方式获取我的异步值而不返回null.this.storage.ready()方法也给了我相同的结果.我的拦截器后调用了auth服务,因此我还没有生成任何令牌.我将如何首先调用我的身份验证服务?
login(userName: string, password: string, route: string = null): any {
this.storage.set('tokens', 'able to retrieve this token value inside interceptor');
this.logout(false);
this.doLogin(userName, password)
.subscribe(response => {
let token:string = JSON.stringify(response.access_token);
this.storage.set('token', token)
}
}
Run Code Online (Sandbox Code Playgroud)
interceptor.ts
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return Observable.fromPromise(
this.getRequestOptionArgs(options)
).mergeMap((options) => {
return super.get(url, options)
})
}
private getRequestOptionArgs(options?: RequestOptionsArgs) {
return this.storage.get('token').then((token) => {
console.log(token, 'token for the get')
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers();
}
if (token !== null) {
options.headers.append('Authorization', 'Bearer ' + token);
}
options.headers.append('Content-Type', 'application/json');
return options;
});
}
Run Code Online (Sandbox Code Playgroud)
我认为问题在于你StorageService正在返回null,而不是拦截器的问题。
存储服务使用 Promise,这意味着它只会发出一个值。如果您收到了null,那么我猜您还没有存储令牌。
您首先从哪里获得令牌?服务器?在这种情况下,第一个请求将没有令牌。
但是...您说过,当您localStorage直接(同步)访问时,您会得到一个值并且一切正常。所以我假设您已经存储了一个令牌。
查看离子存储的文档,看起来还有另一种可能性。存储有ready方法,所以可能存储还没有准备好。
您可以尝试这样的操作(未经测试),首先等待准备好的承诺解决,然后再尝试获取令牌:
import { Injectable } from '@angular/core';
import { HttpErrorResponse, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/observable/fromPromise';
@Injectable()
export class Interceptor implements HttpInterceptor {
constructor (private storage: StorageService) {}
intercept (request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// chain the ready promise with the get token promise
return Observable.fromPromise(this.storage.ready().then(this.storage.get('token')))
.mergeMap((token: string) => {
const authReq = request.clone({
setHeaders: {
Authorization: token
}
});
return next.handle(authReq);
});
}
}
Run Code Online (Sandbox Code Playgroud)
只是一个猜测...
| 归档时间: |
|
| 查看次数: |
1289 次 |
| 最近记录: |