【问题标题】:Angular 6 set withCredentials to true with every HttpClient call每次 HttpClient 调用时,Angular 6 都将 withCredentials 设置为 true
【发布时间】:2018-10-16 11:04:56
【问题描述】:

如果您希望凭据(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

【问题讨论】:

    标签: angular http apache-commons-httpclient


    【解决方案1】:

    创建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 {}
    

    【讨论】:

    • const 复制请求 = request.clone({withCredentials: true});返回 next.handle(copiedReq) 更清晰。
    • 我称之为 requestCopy ;-)
    【解决方案2】:

    这里有两个选择 -

    1. HttpInterceptor

    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 {}
    

    token.interceptor.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());
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-04
      • 2017-11-05
      • 1970-01-01
      • 2021-10-20
      • 2018-04-28
      • 1970-01-01
      • 2020-05-21
      • 2019-02-23
      相关资源
      最近更新 更多