web-dev-qa-db-fra.com

Angular 2 Basic Authentication ne fonctionne pas

J'essaie de connecter/faire une demande POST à une API avec Angular2, c'est une API très simple avec un mot de passe d'authentification de base . Lorsque vous désactivez le mot de passe sur l'API, tout fonctionne comme prévu. Mais lorsque j'active l'authentification de base, Angular ne peut plus se connecter à l'API. Dans Postman, tout fonctionne. J'ai essayé le suivant sans succès.

J'ai deux en-têtes "Content-Type" et "Authorization"

headers.append("Content-Type", "application/x-www-form-urlencoded");

J'ai essayé ces deux en-têtes.

headers.append("Authorization", "Basic " + btoa(Username + ":" + Password)); 
headers.append("Authorization", "Basic VXNlcm5hbWU6UGFzc3dvcmQ=");

La seule chose que je puisse trouver est que dans les en-têtes de la demande RAW, il n’ya qu’une ligne avec les noms des en-têtes, mais les valeurs manquent:

Access-Control-Request-Headers: authorization, content-type

En-têtes bruts:

#Request Headers
OPTIONS /shipment HTTP/1.1
Host: api.example.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Access-Control-Request-Headers: authorization, content-type
Accept: */*
Referer: http://localhost:4200/address
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,nl;q=0.6

J'espère que quelqu'un peut aider

23
Peter

Version simplifiée pour ajouter des en-têtes personnalisés à votre demande:

import {Injectable} from '@angular/core';
import {Http, Headers} from '@angular/http';

@Injectable()
export class ApiService {

   constructor(private _http: Http) {}

   call(url): Observable<any> {
      let username: string = 'username';
      let password: string = 'password';
      let headers: Headers = new Headers();
      headers.append("Authorization", "Basic " + btoa(username + ":" + password)); 
      headers.append("Content-Type", "application/x-www-form-urlencoded");
      return this._http.post(url, data, {headers: headers})
    }
}

Il est difficile de déterminer où vous vous êtes trompé, car le code que vous appelez http vous manque. Mais cet exemple devrait fonctionner pour vous

25
PierreDuc

J'ai eu le même problème dans mon application.

Comme vous pouvez le constater, la demande envoyée n'est pas POST mais OPTION (vérification préalable) 

https://developer.mozilla.org/fr/docs/HTTP/Access_control_CORS

Vous devez autoriser la demande OPTIONS du côté de votre API. Si vous avez une application Spring, vous pouvez simplement ajouter ceci à la configuration de Spring Security: 

    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                **.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()**
(..)

}

Dans mon cas ça marche

2
VANILKA

Cela a résolu mes problèmes:
Angular2 http post - comment envoyer l’en-tête d’autorisation?

D'accord. J'ai trouvé un problème.

Ce n'était pas du côté angulaire. Pour être honnête, il n'y avait aucun problème.

La raison pour laquelle j’ai été incapable d’exécuter ma demande avec succès était que mon application serveur ne traitait pas correctement la demande OPTIONS.

Pourquoi OPTIONS, pas POST? Mon application de serveur est sur l'hôte différent, alors frontend. À cause de CORS, mon navigateur convertissait POST en OPTION: http://restlet.com/blog/2015/12/15/understanding-and-using-cors/

Avec l'aide de cette réponse: Autonome Spring OAuth2 JWT Authorization Server + CORS

J'ai mis en place un filtre approprié sur mon application côté serveur.

Merci à @Supamiu - la personne qui m'a pointé du doigt et que je n'envoie pas POST du tout.

2
Michal

jrcastillo a suggéré une autre option ici

J'ai passé tant d'heures _ à essayer de résoudre ce problème et celui-ci a résolu mon problème.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}

J'étais un peu plus spécifique à la fin, car cela affectait mon chemin d'accès / login et j'ai donc fait ceci:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.OPTIONS, "/api/**");
}
2
rjdkolb

Le problème est avec le serveur principal. Tout navigateur envoie une demande de contrôle en amont faisant une demande d’origine croisée. Dans ce cas, le serveur principal ne traite pas correctement la demande de contrôle en amont. Essayez de faire la configuration cors sur le serveur principal. Cela résoudra ce problème.

0
Siddhant