Angular 6 在每次 HttpClient 调用时将 withCredentials 设置为 true

问题描述 投票:0回答:3

如果您希望凭证(cookie 身份验证令牌)可通过调用传递,则需要在 httpclient 调用中添加

{ withCredentials: true }
。像这样的东西:

import { HttpClient  } from '@angular/common/http';
...
constructor(private httpclient: HttpClient) { }

this.httpclient.get(url, { withCredentials: true })

我只是想知道是否有办法在每次通话时预设

{ withCredentials: true }
。我不想每次打电话时都添加
{ withCredentials: true }

这是一个相关的问题,但我不确定这是否适用于

HttpClient

javascript angular http rxjs apache-commons-httpclient
3个回答
28
投票

创建一个

HttpInterceptor

@Injectable()
export class CustomInterceptor implements HttpInterceptor { 
    
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
        request = request.clone({
            withCredentials: true
        });
    
        return next.handle(request);
    }
}

@NgModule({
    bootstrap: [AppComponent],
    imports: [...],
    providers: [
      {
        provide: HTTP_INTERCEPTORS,
        useClass: CustomInterceptor ,
        multi: true
      }
    ]
})
export class AppModule {}

4
投票

您有两个选择 -

  1. Http拦截器

auth.service.ts

如果您正在编写任何需要立即或稍后进行凭据验证的标准应用程序,那么您将需要

AuthService
。不过,如果您愿意,您现在可以忽略。

    // src/app/auth/auth.service.ts
    import { Injectable } from '@angular/core';
    import decode from 'jwt-decode';
    @Injectable()
    export class AuthService {
      public getToken(): string {
        return localStorage.getItem('token');
      }
      public isAuthenticated(): boolean {
        // get the token
        const token = this.getToken();
        // return a boolean reflecting 
        // whether or not the token is expired
        return tokenNotExpired(null, token);
      }
    }

app.module.ts

提供

HTTP_INTERCEPTORS
,它将拦截您的所有请求。

       // src/app/app.module.ts
    import { HTTP_INTERCEPTORS } from '@angular/common/http';
    import { TokenInterceptor } from './../auth/token.interceptor';
    @NgModule({
      bootstrap: [AppComponent],
      imports: [...],
      providers: [
        {
          provide: HTTP_INTERCEPTORS,
          useClass: TokenInterceptor,
          multi: true
        }
      ]
    })
    export class AppModule {}

令牌.拦截器.ts

这是每个 HTTP 请求都会经过的拦截器。

    // src/app/auth/token.interceptor.ts
    import { Injectable } from '@angular/core';
    import {
      HttpRequest,
      HttpHandler,
      HttpEvent,
      HttpInterceptor
    } from '@angular/common/http';
    import { AuthService } from './auth/auth.service';
    import { Observable } from 'rxjs/Observable';
    @Injectable()
    export class TokenInterceptor implements HttpInterceptor {
      constructor(public auth: AuthService) {}
      intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        
        request = request.clone({
          setHeaders: {
            Authorization: `Bearer ${this.auth.getToken()}`
          }
        });
        return next.handle(request);
      }
    }
  1. 覆盖标准HttpClient

app.module.ts

        @NgModule({
            providers: [ // expose our Services and Providers into Angular's dependency injection
                {provide: HttpClient, useClass: ExtendedHttpService},
            ]
        })
        export class AppModule {
    }

扩展-http.service.ts

    import {Injectable, Injector} from '@angular/core';
    import {Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers} from '@angular/http';
    import {Observable} from 'rxjs/Observable';
    import {Router} from '@angular/router';
    import {AuthService} from './auth.service';
    import 'rxjs/add/operator/catch';
    import 'rxjs/add/observable/throw';
    
    @Injectable()
    export class ExtendedHttpService extends HttpClient {
        private router: Router;
        private authService: AuthService;
    
        constructor(backend: XHRBackend, defaultOptions: RequestOptions, private injector: Injector) {
            super(backend, defaultOptions);
    
        }
    
        request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    
            if (typeof url === 'string') {
                if (!options) {
                    options = {headers: new Headers()};
                }
                this.setHeaders(options);
            } else {
                this.setHeaders(url);
            }
            //console.log("url: " , url , ", Options:" , options);
            return super.request(url, options).catch(this.catchErrors());
        }
    
        private catchErrors() {
    
            return (res: Response) => {
                if (this.router == null) {
                    this.router = this.injector.get(Router);
                }
                if (res.status === 401 || res.status === 403) {
                    //handle authorization errors
                    //in this example I am navigating to login.
                    console.log("Error_Token_Expired: redirecting to login.");
                    this.authService.logout();
                }
                return Observable.throw(res);
            };
        }
    
        private setHeaders(objectToSetHeadersTo: Request | RequestOptionsArgs) {
    
            if (this.authService == null) {
                this.authService = this.injector.get(AuthService);
            }
            //add whatever header that you need to every request
            //in this example I could set the header token by using authService that I've created
            objectToSetHeadersTo.headers.set('Authorization', this.authService.getAuthToken());
        }
    }

0
投票

我知道这个问题要求 Angular 6 应用程序的解决方案,但是,对于那些寻找 Angular 17 解决方案的人 - 就像我一样 - 我们开始:

credential.interceptor.ts

import { HttpInterceptorFn } from '@angular/common/http';

export const credentialsInterceptor: HttpInterceptorFn = (request, next) => {
  const modifiedRequest = request.clone({
    withCredentials: true
  });
  return next(modifiedRequest);
};

app.config.ts

import { ApplicationConfig } from '@angular/core';

import { provideHttpClient,
         withFetch,
         withInterceptors } from '@angular/common/http';

import { credentialsInterceptor } from './credentials.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    // ...
    provideHttpClient(withFetch(), withInterceptors([credentialsInterceptor])),
  ]
};
© www.soinside.com 2019 - 2024. All rights reserved.