이후의 모든 요청에 대해 사용자가 로그인 한 후 일부 권한 부여 헤더를 설정해야합니다.
특정 요청에 대한 헤더를 설정하려면
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
그러나 이러한 방식으로 모든 요청에 대해 요청 헤더를 수동으로 설정하는 것은 불가능합니다.
사용자가 로그인 한 후 헤더 설정을 설정하고 로그 아웃시 해당 헤더를 제거하려면 어떻게합니까?
답변
대답하기 위해 Http
Angular 에서 원본 객체 를 래핑하는 서비스를 제공 할 수 있습니다 . 아래에 설명 된 것과 같은 것.
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 .
답변
HTTP 인터셉터는 사용할 새로운 통해 HttpClient
에서 @angular/common/http
, 각도 4.3.x에서 버전 이후의 등 .
모든 요청에 대해 헤더를 추가하는 것은 매우 간단합니다.
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
} from '@angular/common/http';
import { Observable } from 'rxjs';
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.set('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 {}
답변
BaseRequestOptions
이 시나리오에서는 확장 이 큰 도움이 될 수 있습니다. 다음 코드를 확인하십시오.
import {provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS, Headers, Http, BaseRequestOptions} from 'angular2/http';
import {AppCmp} from './components/app/app';
class MyRequestOptions extends BaseRequestOptions {
constructor () {
super();
this.headers.append('My-Custom-Header','MyCustomHeaderValue');
}
}
bootstrap(AppCmp, [
ROUTER_PROVIDERS,
HTTP_PROVIDERS,
provide(RequestOptions, { useClass: MyRequestOptions })
]);
모든 통화에 ‘내 맞춤 헤더’가 포함되어야합니다.
최신 정보:
위 코드 대신 언제든지 헤더를 변경할 수 있도록 다음 코드를 사용하여 새 헤더를 추가 할 수도 있습니다.
this.http._defaultOptions.headers.append('Authorization', 'token');
당신이 할 수있는 삭제
this.http._defaultOptions.headers.delete('Authorization');
또한 값을 설정하는 데 사용할 수있는 다른 기능이 있습니다.
this.http._defaultOptions.headers.set('Authorization', 'token');
위의 솔루션은 여전히 타자기 컨텍스트에서 완전히 유효하지 않습니다. _defaultHeaders는 보호되어 있으며 이와 같이 사용해서는 안됩니다. 빠른 수정을 위해 위의 솔루션을 권장하지만 오랫동안 인증을 처리하는 http 호출 주위에 자신의 래퍼를 작성하는 것이 좋습니다. 더 좋고 깨끗한 auth0의 다음 예제를 보자.
https://github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts
업데이트-2018 년 6 월
많은 사람들 이이 솔루션을 사용하는 것을 보았지만 그렇지 않으면 조언 할 것입니다. 전 세계에 헤더를 추가하면 앱에서 나가는 모든 API 호출에 인증 토큰이 전송 됩니다. 따라서 인터콤이나 zendesk 또는 다른 API와 같은 타사 플러그인으로가는 API 호출에도 승인 헤더가 있습니다. 이로 인해 큰 보안 결함이 발생할 수 있습니다. 대신 인터셉터를 전역 적으로 사용하지만 발신 전화가 서버의 API 끝점을 향하는 지 여부를 수동으로 확인한 다음 인증 헤더를 첨부하십시오.
답변
답변이 늦었지만 다른 사람에게 도움이 될 수 있습니다. @NgModule
사용될 때 모든 요청에 헤더를 삽입하려면 다음을 수행하십시오.
(Angular 2.0.1에서 이것을 테스트했습니다)
/**
* Extending BaseRequestOptions to inject common headers to all requests.
*/
class CustomRequestOptions extends BaseRequestOptions {
constructor() {
super();
this.headers.append('Authorization', 'my-token');
this.headers.append('foo', 'bar');
}
}
이제 @NgModule
다음 을 수행하십시오.
@NgModule({
declarations: [FooComponent],
imports : [
// Angular modules
BrowserModule,
HttpModule, // This is required
/* other modules */
],
providers : [
{provide: LocationStrategy, useClass: HashLocationStrategy},
// This is the main part. We are telling Angular to provide an instance of
// CustomRequestOptions whenever someone injects RequestOptions
{provide: RequestOptions, useClass: CustomRequestOptions}
],
bootstrap : [AppComponent]
})
답변
에서 Angular 2.1.2
내가 확장하여이 접근 각도 HTTP를 :
import {Injectable} from "@angular/core";
import {Http, Headers, RequestOptionsArgs, Request, Response, ConnectionBackend, RequestOptions} from "@angular/http";
import {Observable} from 'rxjs/Observable';
@Injectable()
export class HttpClient extends Http {
constructor(protected _backend: ConnectionBackend, protected _defaultOptions: RequestOptions) {
super(_backend, _defaultOptions);
}
_setCustomHeaders(options?: RequestOptionsArgs):RequestOptionsArgs{
if(!options) {
options = new RequestOptions({});
}
if(localStorage.getItem("id_token")) {
if (!options.headers) {
options.headers = new Headers();
}
options.headers.set("Authorization", localStorage.getItem("id_token"))
}
return options;
}
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
options = this._setCustomHeaders(options);
return super.request(url, options)
}
}
그런 다음 내 App Providers에서 커스텀 팩토리를 사용하여 ‘Http’를 제공 할 수있었습니다.
import { RequestOptions, Http, XHRBackend} from '@angular/http';
import {HttpClient} from './httpClient';
import { RequestOptions, Http, XHRBackend} from '@angular/http';
import {HttpClient} from './httpClient';//above snippet
function httpClientFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions): Http {
return new HttpClient(xhrBackend, requestOptions);
}
@NgModule({
imports:[
FormsModule,
BrowserModule,
],
declarations: APP_DECLARATIONS,
bootstrap:[AppComponent],
providers:[
{ provide: Http, useFactory: httpClientFactory, deps: [XHRBackend, RequestOptions]}
],
})
export class AppModule {
constructor(){
}
}
이제 모든 Http 메서드를 선언 할 필요가 없으며 http
응용 프로그램 전체에서 정상적으로 사용할 수 있습니다 .
답변
Angular 2 Http
Provider 를 확장하여 사용자 정의 Http 클래스를 작성하고 사용자 정의 Http 클래스 에서 constructor
and request
메소드를 대체하십시오 . 아래 예제 Authorization
는 모든 http 요청에 헤더를 추가합니다 .
import {Injectable} from '@angular/core';
import {Http, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Headers} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class HttpService extends Http {
constructor (backend: XHRBackend, options: RequestOptions) {
let token = localStorage.getItem('auth_token'); // your custom token getter function here
options.headers.set('Authorization', `Bearer ${token}`);
super(backend, options);
}
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
let token = localStorage.getItem('auth_token');
if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
if (!options) {
// let's make option object
options = {headers: new Headers()};
}
options.headers.set('Authorization', `Bearer ${token}`);
} else {
// we have to add the token to the url object
url.headers.set('Authorization', `Bearer ${token}`);
}
return super.request(url, options).catch(this.catchAuthError(this));
}
private catchAuthError (self: HttpService) {
// we have to pass HttpService's own instance here as `self`
return (res: Response) => {
console.log(res);
if (res.status === 401 || res.status === 403) {
// if not authenticated
console.log(res);
}
return Observable.throw(res);
};
}
}
그런 다음 주요 구성 app.module.ts
를 제공 할 수 XHRBackend
는 AS ConnectionBackend
공급자 및 RequestOptions
사용자 지정 HTTP 클래스 :
import { HttpModule, RequestOptions, XHRBackend } from '@angular/http';
import { HttpService } from './services/http.service';
...
@NgModule({
imports: [..],
providers: [
{
provide: HttpService,
useFactory: (backend: XHRBackend, options: RequestOptions) => {
return new HttpService(backend, options);
},
deps: [XHRBackend, RequestOptions]
}
],
bootstrap: [ AppComponent ]
})
그런 다음 서비스에서 사용자 정의 http 제공자를 사용할 수 있습니다. 예를 들면 다음과 같습니다.
import { Injectable } from '@angular/core';
import {HttpService} from './http.service';
@Injectable()
class UserService {
constructor (private http: HttpService) {}
// token will added automatically to get request header
getUser (id: number) {
return this.http.get(`/users/${id}`).map((res) => {
return res.json();
} );
}
}
다음은 포괄적 인 가이드입니다 -http : //adonespitogo.com/articles/angular-2-extending-http-provider/
답변
Angular 5 이상에서는 요청 및 응답 작업을 일반화하기 위해 HttpInterceptor를 사용할 수 있습니다. 이를 통해 중복을 피할 수 있습니다.
1) 공통 헤더
2) 응답 타입 지정
3) 질의 요청
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpResponse,
HttpErrorResponse
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
@Injectable()
export class AuthHttpInterceptor implements HttpInterceptor {
requestCounter: number = 0;
constructor() {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
responseType: 'json',
setHeaders: {
Authorization: `Bearer token_value`,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
});
return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// do stuff with response if you want
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
// do stuff with response error if you want
}
});
}
}
이 AuthHttpInterceptor 클래스를 HttpInterceptors의 공급자로 사용할 수 있습니다.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app.routing-module';
import { AuthHttpInterceptor } from './services/auth-http.interceptor';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
BrowserAnimationsModule,
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthHttpInterceptor,
multi: true
}
],
exports: [],
bootstrap: [AppComponent]
})
export class AppModule {
}