312

I'm implementing an API made by other colleagues with Apiary.io, in a Windows Store app project.

They show this example of a method I have to implement:

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

In this and some other methods, I need to have a header with a token that I get before.

Here's an image of Postman (chrome extension) with the header I'm talking about: enter image description here

How do I add that Authorization header to the request?

2

6 Answers 6

568

A later answer, but because no one gave this solution...

If you do not want to set the header directly on the HttpClient instance by adding it to the DefaultRequestHeaders (to not send it to all the requests you will make with it), you could set headers per request.

But you will be obliged to use the SendAsync() method, the only method that takes a HttpRequestMessage instance in input (that allows configuring headers).

This is the right solution if you want to reuse the HttpClient -- which is a best practice for

Use it like this:

using (var requestMessage =
            new HttpRequestMessage(HttpMethod.Get, "https://your.site.com"))
{
    requestMessage.Headers.Authorization =
        new AuthenticationHeaderValue("Bearer", your_token);
    
    await httpClient.SendAsync(requestMessage);
}
Sign up to request clarification or add additional context in comments.

16 Comments

Seems safer to not use DefaultRequestHeaders if the value changes frequently.
Note you very likely need requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", your_token); "Bearer" would be an invalid HTTP header
@JCKodel it would have added noise because you're not necessary obliged to use using but could instantiate in the constructor and dispose in the Dispose()
I never said use using on HttpClient (this is bad), I said on HttpRequesMessage (because it have unmanaged memory buffers for streaming that MUST be disposed after the use). The request and response are and must be disposed every request (otherwise you'll keep large memory chunks locked for a long time). The HttpClient is reusable, to an extend.
The best is to have 1 httpClient for each api/server to query and keep it as long as possible. Which is most of the time incompatible with using using. Static could be good (at least better that multiple instances) but better is to use dependency injection. One instance kept all along the application lifetime is good.
|
264

When using GetAsync with the HttpClient you can add the authorization headers like so:

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

This does add the authorization header for the lifetime of the HttpClient so is useful if you are hitting one site where the authorization header doesn't change.

Here is an detailed SO answer

4 Comments

-1 because HttpClient must be reusable (see aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong). If it must be reusable, setting the default request headers is a bad practice.
@JCKödel That's a false assumption you are making. If you are always calling the same site with the same credentials for the lifetime of the HttpClient using the DefaultRequestHeaders saves you from having to continuously set them again with the same values. You should re-read that article it talks about using the same instance of the HttpClient, it makes no statements about default request headers being bad practice. If I am calling only one site ever with the HTTP client which in practice does happen using the DefaultRequestHeaders saves you from having to set them each time.
@JCKödel, though you are incorrect in your assumption, I upvoted your comment, because you brought up an important point. Added greater clarity to the answer.
@kmcnamee, what if I need to pass two tokens?
119

The accepted answer works but can get complicated when you want to try adding Accept headers. This is what I ended up with. It seems simpler to me, so I think I'll stick with it in the future:

client.DefaultRequestHeaders.Add("Accept", "application/*+xml;version=5.1");
client.DefaultRequestHeaders.Add("Authorization", "Basic " + authstring);

2 Comments

But I call API one more time, that time I face error like Cannot add value because header 'Authorization' does not support multiple values.
@akash-limbani If you're reusing the same client, check before trying add. ``` if (!client.DefaultRequestHeaders.Contains("Authorization")) { client.DefaultRequestHeaders.Add("Authorization", "Basic " + authstring); } ```
19

Sometimes, you only need this code.

 httpClient.DefaultRequestHeaders.Add("token", token);

Comments

8

Following the greenhoorn's answer, you can use "Extensions" like this:

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

And use:

string _tokenUpdated = "TOKEN";
HttpClient _client;
_client.AddTokenToHeader(_tokenUpdated).GetAsync("/api/values")

Comments

5

These days, if you are using MS Dependency Injection, it's highly recomended to plug in the IHttpClientFactory:

builder.Services.AddHttpClient("GitHub", httpClient =>
{
    httpClient.BaseAddress = new Uri("https://api.github.com/");

    // using Microsoft.Net.Http.Headers;
    // The GitHub API requires two headers.
    httpClient.DefaultRequestHeaders.Add(
        HeaderNames.Accept, "application/vnd.github.v3+json");
    httpClient.DefaultRequestHeaders.Add(
        HeaderNames.UserAgent, "HttpRequestsSample");
});

var httpClient = _httpClientFactory.CreateClient("GitHub");

This way you avoid adding default request headers to a globally shared httpclient and moreover don't have to deal with manual creation of the HttpRequestMessage.

Source: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-6.0#consumption-patterns

1 Comment

@CarlosSánchezLópez Understand, to further explain my point, my advice is: always delegate the creation of HttpClient to the HttpClientFactory. HttpClient is a strange object that could lead to memory leaks if not handled correctly. For example, one shouldn't create and dispose it repetitively (better to carefully share a singleton instance): to sum up, even for a simple project use the httpclientfactory. BTW you do not need the full blow aspnet core just a generic host (learn.microsoft.com/en-us/aspnet/core/fundamentals/host/…)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.