我需要在用户登录后为每个后续请求设置一些授权头。
为特定请求设置头信息,
import {Headers} from 'angular2/http';
var headers = new Headers();
headers.append(headerName, value);
// HTTP POST using these headers
this.http.post(url, data, {
headers: headers
})
// do something with the response
参考
但是,以这种方式为每个请求手动设置请求头是不可行的。
我如何设置头设置一旦用户登录,也删除注销这些头?
为了回答你的问题,你可以提供一个服务来包装Angular的原始Http对象。如下所述。
import {Injectable} from '@angular/core';
import {Http, Headers} from '@angular/http';
@Injectable()
export class HttpClient {
constructor(private http: Http) {}
createAuthorizationHeader(headers: Headers) {
headers.append('Authorization', 'Basic ' +
btoa('username:password'));
}
get(url) {
let headers = new Headers();
this.createAuthorizationHeader(headers);
return this.http.get(url, {
headers: headers
});
}
post(url, data) {
let headers = new Headers();
this.createAuthorizationHeader(headers);
return this.http.post(url, data, {
headers: headers
});
}
}
而不是注入Http对象,你可以注入这个对象(HttpClient)。
import { HttpClient } from './http-client';
export class MyComponent {
// Notice we inject "our" HttpClient here, naming it Http so it's easier
constructor(http: HttpClient) {
this.http = httpClient;
}
handleSomething() {
this.http.post(url, data).subscribe(result => {
// console.log( result );
});
}
}
我还认为可以通过提供自己的类来扩展Http类,从而为Http类使用多个提供者……请看这个链接:http://blog.thoughtram.io/angular2/2015/11/23/multi-providers-in-angular-2.html。
你可以在你的路由中使用canActive,如下所示:
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService, private router: Router) {}
canActivate() {
// If user is not logged in we'll send them to the homepage
if (!this.auth.loggedIn()) {
this.router.navigate(['']);
return false;
}
return true;
}
}
const appRoutes: Routes = [
{
path: '', redirectTo: '/deals', pathMatch: 'full'
},
{
path: 'special',
component: PrivateDealsComponent,
/* We'll use the canActivate API and pass in our AuthGuard.
Now any time the /special route is hit, the AuthGuard will run
first to make sure the user is logged in before activating and
loading this route. */
canActivate: [AuthGuard]
}
];
摘自:https://auth0.com/blog/angular-2-authentication
我已经能够选择一个更简单的解决方案>添加一个新的头到默认选项合并或加载你的api得到(或其他)函数。
get(endpoint: string, params?: any, options?: RequestOptions) {
if (!options) {
options = new RequestOptions();
options.headers = new Headers( { "Accept": "application/json" } ); <<<<
}
// [...]
}
当然,你可以在默认选项或类中具体化这个头。
这是Ionic生成的api。ts @Injectable()导出类API {}
这是非常快的,它为我工作。我不想要json/ld格式。
HTTP拦截器是实现这一点的正确方法。在这里没有看到关于如何完全实现它的适当文档,所以我包含了谷歌官方指南的链接。在实现之前,我已经通读了文档,因为在安全性和使用多个拦截器包方面存在许多潜在的缺陷。
https://angular.io/guide/http#intercepting-requests-and-responses
import { Injectable } from '@angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
/** Pass untouched request through to the next request handler. */
@Injectable()
export class NoopInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
return next.handle(req);
}
}
从Angular 4.3开始,HTTP拦截器现在可以通过新的HttpClient @angular/common/ HTTP使用了。X版本及更高版本。
现在为每个请求添加头文件非常简单:
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { Injectable } from '@angular/core';
@Injectable()
export class AddHeaderInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Clone the request to add the new header
const clonedRequest = req.clone({ headers: req.headers.append('Authorization', 'Bearer 123') });
// Pass the cloned request instead of the original request to the next handle
return next.handle(clonedRequest);
}
}
有一个不可变性的原则,这就是为什么在设置新内容之前需要克隆请求。
由于编辑头部是一个非常常见的任务,实际上有一个快捷方式(在克隆请求时):
const clonedRequest = req.clone({ setHeaders: { Authorization: 'Bearer 123' } });
创建拦截器之后,你应该使用HTTP_INTERCEPTORS提供的方法注册它。
import { HTTP_INTERCEPTORS } from '@angular/common/http';
@NgModule({
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: AddHeaderInterceptor,
multi: true,
}],
})
export class AppModule {}