web-dev-qa-db-fra.com

Angular 4 - paramètre withCredentials à chaque demande - cors cookie

Mon client angular est séparé du serveur et j’ai activé cors sur le serveur, tout fonctionne correctement sauf le fait que mon authentification échoue car le cookie n’a pas été ajouté aux demandes.

Après une recherche en ligne, j'ai trouvé que je devrais définir {withCredentials : true} sur chaque requête http. J'ai réussi à le faire sur une seule demande et cela fonctionne, mais pas sur toutes les demandes.

J'ai essayé d'utiliser BrowserXhr Comment envoyer "Cookie" dans l'en-tête de la requête pour toutes les requêtes dans Angular2? mais cela ne fonctionne pas et il est également obsolète.

J'ai aussi essayé RequestOptions mais cela n'a pas fonctionné.

Que puis-je faire pour définir {withCredentials: true} sur chaque demande http?

Éditer plus tard:

@Injectable()
export class ConfigInterceptor implements HttpInterceptor {

  constructor(private csrfService: CSRFService) {

  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let token = this.csrfService.getCSRF() as string;
    const credentialsReq = req.clone({withCredentials : true, setHeaders: { "X-XSRF-TOKEN": token } });
    return next.handle(credentialsReq);
  }
}
29
exilonX

Vous pouvez utiliser un HttpInterceptor.

@Injectable()
export class CustomInterceptor implements HttpInterceptor {

    constructor() {
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        request = request.clone({
            withCredentials: true
        });

        return next.handle(request);
    }
}

Ensuite, vous devez le fournir:

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

Source et explication complète

36
Venomy

Un autre moyen peut-être plus simple consiste à créer votre propre ApiService . Il utiliserait un HttpClient injecté. Toutes les demandes XHR utiliseraient ApiService au lieu de HttpClient directement.

Voici un exemple d'implémentation:

https://github.com/gothinkster/angular-realworld-example-app/blob/63f5cd879b5e1519abfb30302727c37ff7b890d92/src/app/core/services/api.service.ts

Une partie du code que j'ai modifié:

@Injectable()
export class ApiService {

  private httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
    withCredentials: true // to allow cookies to go from "https://localhost:4567" to "http://localhost:5678"
  };

  constructor(
    private http: HttpClient
  ) { }

  private formatErrors(error: any) {
    return throwError(error.error);
  }

  get(path: string, params: HttpParams = new HttpParams()): Observable<any> {
    return this.http.get(`${environment.api_url}${path}`, { params })
      .pipe(catchError(this.formatErrors));
  }

  put(path: string, body: Object = {}): Observable<any> {
    return this.http.put(
      `${environment.api_url}${path}`,
      JSON.stringify(body),
      this.httpOptions
    ).pipe(catchError(this.formatErrors));
  }

  post(path: string, body: Object = {}): Observable<any> {
    return this.http.post(
      `${environment.api_url}${path}`,
      JSON.stringify(body),
      this.httpOptions
    ).pipe(catchError(this.formatErrors));
  }
2
Jess