Instance tunggal HttpClient dengan header autentikasi berbeda
Mengingat bahwa .net HttpClient telah dirancang dengan mempertimbangkan penggunaan kembali dan dimaksudkan untuk berumur panjang dan kebocoran memori telah dilaporkan dalam kasus yang berumur pendek. Garis panduan apa yang ada di mana Anda ingin membuat panggilan tenang ke titik akhir tertentu menggunakan token pembawa yang berbeda (atau tajuk otorisasi) saat memanggil titik akhir untuk beberapa pengguna?
private void CallEndpoint(string resourceId, string bearerToken) {
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("bearer", bearerToken);
var response = await httpClient.GetAsync($"resource/{resourceid}");
}
Mengingat kode di atas dapat dipanggil oleh sejumlah utas pada aplikasi web, sangat mungkin bahwa header yang disetel pada baris pertama tidak sama dengan yang digunakan saat memanggil sumber daya.
Tanpa menyebabkan perselisihan menggunakan kunci dan memelihara aplikasi web tanpa kewarganegaraan, apa pendekatan yang disarankan untuk membuat dan membuang HttpClients untuk satu titik akhir (Praktik saya saat ini adalah membuat satu klien per titik akhir)?
Lingkaran kehidupan
Meskipun HttpClient secara tidak langsung mengimplementasikan antarmuka IDisposable, penggunaan HttpClient yang disarankan adalah tidak membuangnya setelah setiap permintaan. Objek HttpClient dimaksudkan untuk hidup selama aplikasi Anda perlu membuat permintaan HTTP. Memiliki objek di beberapa permintaan memungkinkan tempat untuk menyetel DefaultRequestHeaders dan mencegah Anda harus menetapkan ulang hal-hal seperti CredentialCache dan CookieContainer pada setiap permintaan, seperti yang diperlukan dengan HttpWebRequest.
Jawaban
Jika tajuk Anda biasanya akan sama, maka Anda dapat menyetel DefaultRequestHeaders. Tetapi Anda tidak perlu menggunakan properti itu untuk menentukan header. Seperti yang telah Anda tentukan, itu tidak akan berhasil jika Anda akan memiliki banyak utas menggunakan klien yang sama. Perubahan pada tajuk default yang dibuat di satu utas akan memengaruhi permintaan yang dikirim di utas lain.
Meskipun Anda dapat menyetel header default pada klien dan menerapkannya ke setiap permintaan, header sebenarnya adalah properti permintaan. Jadi, jika header dikhususkan untuk permintaan, Anda cukup menambahkannya ke permintaan.
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", bearerToken);
Itu berarti Anda tidak dapat menggunakan metode sederhana yang tidak melibatkan pembuatan file HttpRequest. Anda harus menggunakan
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
didokumentasikan di sini .
Beberapa orang merasa terbantu menggunakan metode ekstensi untuk mengisolasi kode yang memperbarui header dari metode lainnya.
Contoh metode GET dan POST yang dilakukan melalui metode ekstensi yang memungkinkan Anda memanipulasi header permintaan dan lebih banyak HttpRequestMessagesebelum dikirim:
public static Task<HttpResponseMessage> GetAsync
(this HttpClient httpClient, string uri, Action<HttpRequestMessage> preAction)
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
preAction(httpRequestMessage);
return httpClient.SendAsync(httpRequestMessage);
}
public static Task<HttpResponseMessage> PostAsJsonAsync<T>
(this HttpClient httpClient, string uri, T value, Action<HttpRequestMessage> preAction)
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uri)
{
Content = new ObjectContent<T>
(value, new JsonMediaTypeFormatter(), (MediaTypeHeaderValue)null)
};
preAction(httpRequestMessage);
return httpClient.SendAsync(httpRequestMessage);
}
Ini kemudian dapat digunakan seperti berikut:
var response = await httpClient.GetAsync("token",
x => x.Headers.Authorization = new AuthenticationHeaderValue("basic", clientSecret));