【发布时间】:2016-07-10 05:47:31
【问题描述】:
我正在尝试编写一个 Angular 服务,该服务将包装常规 Http 服务并在 Bearer 令牌不可用或无效时自动进行身份验证调用。
这是通过服务进行的常规 GET 调用的示例:
this.httpWithAutomagicAuth
.get("http://localhost:5001/books")
.map(res => res.json())
.subscribe(
data => {
self.data = data;
}
);
这是我对此类服务的非常草率的实现。显然,我没有在代码中使用正确的 ReactiveX 习惯用法。
你可以很容易地注意到我正在尝试构建一个使用 this.login() 返回的另一个 observable 的 observable (Observable.create)。我确信对于这种情况有更好的链接/嵌套 observable 方法。
请提出改进代码的建议:
- 简洁
-
易于阅读和理解
@Injectable() export class HttpWebApiAuthService { constructor(private http: Http) { } // ... public get(url: string, options?: RequestOptionsArgs): Observable<Response> { // TODO this code is for test purpose only (basically, it required to enforce the jwtToken retrieval branch execution) // this.clearJwtToken(); if (!this.getJwtToken()) { return Observable.create( (result: Observer<Response>) => { this.login() .map(res => res.json()) .subscribe( data => { this.saveJwtToken(data.id_token); this.executeGet(url, options) .subscribe(authenticationResult => { result.next(authenticationResult); }); }, error => { console.error("Authentication error", error); }, () => { console.info("Authentication complete"); } ); }, error => { console.error("OBSERVABLE error: ", error); }, () => { console.info("OBSERVABLE complete"); } ); } else { return this.executeGet(url, options); } } private login() : Observable<Response> { const authBody = { "client_id": "...", "username": "...", "password": "...", // ... }; const headers = new Headers(); headers.append("Content-Type", "application/json"); return this.http.post("https://AUTH_URL", JSON.stringify(authBody), { headers: headers }); } // ... }
【问题讨论】:
标签: typescript angular reactive-programming