我正在MVC5 ASP.NET项目中工作,并了解到要从控制器向WEB API发送经过身份验证的请求,我可以执行以下操作将标记添加到标头中(使用示例代码):
public static class APICaller
{
// Use a single instance for HttpClient to reduce overhead
private static readonly HttpClient client = new HttpClient();
//Set the Authorization Header
public static string SetHeader( string token )
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
return("Success");
}
}
在HttpClient线程安全上以这种方式设置标头?其他用户是否有办法访问这个相同的令牌,因为这个HttpClient只有一个实例?
编辑:
我想再问一个问题,以便更好地了解它是如何运作的。每次我使用相同的HttpClient对象发出请求时,是否需要添加标题?
答案 0 :(得分:4)
使用您拥有的方法,一旦您在静态实例上设置了默认请求标头,它将保持设置状态,而无需您继续设置它。这意味着如果您有多个请求进入您的服务器,您可能最终会遇到这样的情况:为一个用户设置了标头,然后在第一个请求将其发出门之前由另一个请求更改。
避免这种情况的一个选择是在使用特定于用户的授权标头时使用SendAsync
。这允许您将标题绑定到特定消息,而不是将其设置为HttpClient
本身的默认消息。
代码有点冗长,但看起来像这样:
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://path/to/wherever"))
{
httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "TheToken");
using (var httpResponseMessage = httpClient.SendAsync(httpRequestMessage))
{
// ...
}
}
正如您所看到的,标题是针对每个请求专门设置的,因此混合标题的问题就消失了。明显的缺点是这种语法更加冗长。
答案 1 :(得分:1)
鉴于此HttpClient只有一个实例,其他用户是否可以访问此相同令牌?
是的,这就是设置默认标题时需要小心的原因。
每次我使用相同的HttpClient对象发出请求时,是否需要添加标头?
不,因为您设置默认标头,使用该对象创建的所有请求都将具有标头。
对于诸如Bearer令牌之类的东西,最好不要放入默认标头,而是通过创建新的HttpRequestMessage
对象,在那里设置所需的标头,然后使用{{1传递请求消息以发送标题和您的请求。