Ajout d'en-têtes lors de l'utilisation de httpClient.GetAsync

153

J'implémente une API créée par d'autres collègues avec Apiary.io, dans un projet d'application Windows Store.

Ils montrent cet exemple de méthode que je dois implémenter:

var baseAddress = new Uri("https://private-a8014-xxxxxx.apiary-mock.com/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{
    using (var response = await httpClient.GetAsync("user/list{?organizationId}"))
    {
        string responseData = await response.Content.ReadAsStringAsync();
    }
}

Dans cette méthode et dans d'autres, j'ai besoin d'un en-tête avec un jeton que j'obtiens auparavant.

Voici une image de Postman (extension chrome) avec l'en-tête dont je parle: entrez la description de l'image ici

Comment ajouter cet en-tête d'autorisation à la demande?

Ric
la source
2
duplication possible de l'en- tête d'autorisation de réglage de HttpClient
Daniel Kelley
5
Avertissement Pour les chercheurs de code potentiels: il s'agit d'une utilisation incorrecte de HttpClient !! Vérifiez aspnetmonsters.com/2016/08/2016-08-27-httpclientsauvais pourquoi.
321X

Réponses:

175

Lorsque vous utilisez GetAsync avec HttpClient, vous pouvez ajouter les en-têtes d'autorisation comme suit:

httpClient.DefaultRequestHeaders.Authorization 
                         = new AuthenticationHeaderValue("Bearer", "Your Oauth token");

Cela ajoute l'en-tête d'autorisation pour la durée de vie du HttpClient, ce qui est utile si vous accédez à un site où l'en-tête d'autorisation ne change pas.

Voici une réponse SO détaillée

kmcnamee
la source
31
-1 car HttpClient doit être réutilisable (voir aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong ). S'il doit être réutilisable, la définition des en-têtes de demande par défaut est une mauvaise pratique.
JCKödel
23
@ JCKödel C'est une fausse supposition que vous faites. Si vous appelez toujours le même site avec les mêmes informations d'identification pendant la durée de vie du HttpClient, l'utilisation de DefaultRequestHeaders vous évite d'avoir à les redéfinir en continu avec les mêmes valeurs. Vous devriez relire cet article dont il parle d'utiliser la même instance de HttpClient, il ne fait aucune déclaration sur les en-têtes de demande par défaut étant une mauvaise pratique. Si j'appelle un seul site avec le client HTTP, ce qui se produit dans la pratique en utilisant DefaultRequestHeaders vous évite d'avoir à les définir à chaque fois.
kmcnamee
@ JCKödel, bien que vous vous trompiez dans votre hypothèse, j'ai voté pour votre commentaire, car vous avez soulevé un point important. Ajout d'une plus grande clarté à la réponse.
Najeeb le
@kmcnamee, que faire si j'ai besoin de passer deux jetons?
Najeeb le
281

Une réponse plus tardive, mais parce que personne n'a donné cette solution ...

Si vous ne souhaitez pas définir l'en-tête de l' HttpClientinstance en l'ajoutant au DefaultRequestHeaders, vous pouvez définir des en-têtes par requête .

Mais vous serez obligé d'utiliser le SendAsync() méthode.

C'est la bonne solution si vous souhaitez réutiliser leHttpClient - ce qui est une bonne pratique pour

Utilisez-le comme ceci:

using (var requestMessage =
            new HttpRequestMessage(HttpMethod.Get, "https://your.site.com"))
{
    requestMessage.Headers.Authorization =
        new AuthenticationHeaderValue("Bearer", your_token);
    httpClient.SendAsync(requestMessage);
}
Philippe
la source
5
Semble plus sûr de ne pas utiliser DefaultRequestHeaders si la valeur change fréquemment.
Jason Rowe
3
Notez que vous avez très probablement besoin que requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", your_token);"Bearer" soit un en-tête HTTP non valide
Chris Marisic
3
Merci pour cela, nous réutilisons notre HttpClient et cela nous a aidés
StevenMcD
2
@JCKodel cela aurait ajouté du bruit car vous n'êtes pas obligé de l'utiliser usingmais pourriez instancier dans le constructeur et disposer dans leDispose()
Philippe
3
Je n'ai jamais dit utiliser usingsur HttpClient (c'est mauvais), j'ai dit sur HttpRequesMessage (car il a des tampons de mémoire non gérés pour le streaming qui DOIVENT être éliminés après l'utilisation). La demande et la réponse sont et doivent être supprimées à chaque demande (sinon, vous garderez les gros blocs de mémoire verrouillés pendant longtemps). Le HttpClientest réutilisable, dans une certaine mesure.
JCKödel
70

La réponse acceptée fonctionne mais peut devenir compliquée lorsque je voulais essayer d'ajouter des en-têtes Accept. C'est ce avec quoi j'ai fini. Cela me semble plus simple alors je pense que je vais m'en tenir à l'avenir:

client.DefaultRequestHeaders.Add("Accept", "application/*+xml;version=5.1");
client.DefaultRequestHeaders.Add("Authorization", "Basic " + authstring);
sirdank
la source
Le moyen le plus simple d'ajouter un en-tête d'autorisation de base
sandyiit
7

Vous pouvez ajouter les en-têtes dont vous avez besoin au HttpClient .

Voici un joli tutoriel à ce sujet.

Cela ne fait pas seulement référence aux requêtes POST, vous pouvez également l'utiliser pour les requêtes GET.

Greenhoorn
la source
URL Github , au cas où le lien du site expirait.
Sen Jacob
5

Suite à la réponse de greenhoorn, vous pouvez utiliser des "Extensions" comme ceci:

  public static class HttpClientExtensions
    {
        public static HttpClient AddTokenToHeader(this HttpClient cl, string token)
        {
            //int timeoutSec = 90;
            //cl.Timeout = new TimeSpan(0, 0, timeoutSec);
            string contentType = "application/json";
            cl.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType));
            cl.DefaultRequestHeaders.Add("Authorization", String.Format("Bearer {0}", token));
            var userAgent = "d-fens HttpClient";
            cl.DefaultRequestHeaders.Add("User-Agent", userAgent);
            return cl;
        }
    }

Et utilise:

string _tokenUpdated = "TOKEN";
HttpClient _client;
_client.AddTokenToHeader(_tokenUpdated).GetAsync("/api/values")
RDyego
la source
-1

Parfois, vous n'avez besoin que de ce code.

 httpClient.DefaultRequestHeaders.Add("token", token);
Jackdon Wang
la source