Adicionando cabeçalhos ao usar httpClient.GetAsync

152

Estou implementando uma API feita por outros colegas do Apiary.io, em um projeto de aplicativo da Windows Store.

Eles mostram este exemplo de um método que eu tenho que implementar:

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

Neste e em alguns outros métodos, preciso ter um cabeçalho com um token que recebo antes.

Aqui está uma imagem do Postman (extensão chrome) com o cabeçalho do qual estou falando: insira a descrição da imagem aqui

Como adiciono esse cabeçalho de autorização à solicitação?

Ric
fonte
2
possível duplicata de Ajuste Autorização cabeçalho de HttpClient
Daniel Kelley
5
Aviso Para possíveis pesquisadores de código: este é um uso incorreto do HttpClient !! Verifique aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong why.
321X

Respostas:

174

Ao usar GetAsync com o HttpClient, você pode adicionar os cabeçalhos de autorização da seguinte forma:

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

Isso adiciona o cabeçalho da autorização por toda a vida útil do HttpClient; portanto, é útil se você estiver acessando um site em que o cabeçalho da autorização não muda.

Aqui está uma resposta SO detalhada

kmcnamee
fonte
31
-1 porque o HttpClient deve ser reutilizável (consulte aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong ). Se for necessário reutilizá-lo, definir os cabeçalhos de solicitação padrão é uma prática ruim.
JCKödel 3/06
22
@ JCKödel Essa é uma suposição falsa que você está fazendo. Se você estiver sempre chamando o mesmo site com as mesmas credenciais durante a vida útil do HttpClient, usando o DefaultRequestHeaders, evitará que seja necessário defini-los novamente novamente com os mesmos valores. Você deve reler o artigo que fala sobre o uso da mesma instância do HttpClient, mas não faz nenhuma declaração sobre os cabeçalhos de solicitação padrão serem uma má prática. Se eu estiver chamando apenas um site com o cliente HTTP, o que, na prática, acontece usando o DefaultRequestHeaders, evita que você precise defini-los sempre.
Kmcnamee 03/06
@ JCKödel, embora você esteja incorreto em sua suposição, eu votei no seu comentário, porque você mencionou um ponto importante. Adicionado maior clareza à resposta.
Najeeb 14/01
@kmcnamee, e se eu precisar passar dois tokens?
Najeeb 14/01
281

Uma resposta posterior, mas porque ninguém deu essa solução ...

Se você não desejar definir o cabeçalho na HttpClientinstância, adicionando-o ao DefaultRequestHeaders, poderá definir cabeçalhos por solicitação .

Mas você será obrigado a usar o SendAsync()método.

Essa é a solução certa se você deseja reutilizar aHttpClient - que é uma boa prática para

Use-o assim:

using (var requestMessage =
            new HttpRequestMessage(HttpMethod.Get, "https://your.site.com"))
{
    requestMessage.Headers.Authorization =
        new AuthenticationHeaderValue("Bearer", your_token);
    httpClient.SendAsync(requestMessage);
}
Philippe
fonte
5
Parece mais seguro não usar DefaultRequestHeaders se o valor for alterado com frequência.
Jason Rowe
3
Note que você muito provável necessidade requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", your_token);"portador" seria um inválido cabeçalho HTTP
Chris Marisic
3
Obrigado por isso, estamos reutilizando o nosso HttpClient e isso nos ajudou
StevenMcD
2
@JCKodel ele teria acrescentado ruído porque você não é necessário obrigados a utilizar usingmas poderia instanciar no construtor e dispor noDispose()
Philippe
3
Eu nunca disse usar o usingHttpClient (isso é ruim), eu disse no HttpRequesMessage (porque há buffers de memória não gerenciados para streaming que DEVEM ser descartados após o uso). A solicitação e a resposta são e devem ser descartadas a cada solicitação (caso contrário, você manterá grandes blocos de memória bloqueados por um longo tempo). O HttpClienté reutilizável, até certo ponto.
JCKödel
70

A resposta aceita funciona, mas pode ficar complicada quando eu quero tentar adicionar cabeçalhos Accept. Foi assim que acabei. Parece mais simples para mim, então acho que vou continuar com isso no futuro:

client.DefaultRequestHeaders.Add("Accept", "application/*+xml;version=5.1");
client.DefaultRequestHeaders.Add("Authorization", "Basic " + authstring);
sirdank
fonte
Maneira mais simples de adicionar cabeçalho de autorização básica
sandyiit
7

Você pode adicionar os cabeçalhos necessários ao HttpClient.

Aqui está um bom tutorial sobre isso.

Isso não se refere apenas a solicitações POST, você também pode usá-lo para solicitações GET.

greenhoorn
fonte
URL do Github , caso o link do site tenha expirado.
Sen Jacob
4

Após a resposta do greenhoorn, você pode usar "Extensões" assim:

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

E use:

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

Às vezes, você só precisa desse código.

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