C# HttpClient调用REST API 获取有效access token仍报Unauthorized问题
问题原因
- 核心原因:调用业务接口的
ListAirports方法未在请求头中携带Bearer格式的授权凭证。你在verifyToken校验方法中手动添加了Authorization头,但业务请求完全没有配置该头,服务端无法识别用户身份,因此返回未授权错误。 - 其他潜在问题:
- 每次请求都新建
HttpClient实例会导致套接字资源耗尽,属于HttpClient的常见错误用法。 - 部分业务接口可能要求和获取Token的请求一致携带
Referer请求头,缺少该头也可能触发权限拦截。 getAccessToken方法中混用异步和同步等待:response.Content.ReadAsStringAsync().Result存在死锁风险,应该统一用await等待异步方法。
- 每次请求都新建
解决方案
1. 统一封装HttpClient实例,避免重复创建
将HttpClient设置为静态单例(如果是ASP.NET Core环境推荐用IHttpClientFactory注入),减少资源开销:
// 全局静态HttpClient实例,全局只需初始化一次 private static readonly HttpClient _httpClient = new HttpClient(); // 基础配置,程序启动时执行一次即可 public static void InitHttpClient() { _httpClient.DefaultRequestHeaders.Add("Referer", "http://admin.altrabo.com/"); }
2. 修复getAccessToken方法的异步逻辑
public static async Task<string> getAccessToken() { var tokenClient = new TokenClient() { client_Id= -1, username= "admin", password= "Main@dm!n", grant_Type= "Main@dm!n", externalProvider= 1, }; HttpResponseMessage response = await _httpClient.PostAsJsonAsync<TokenClient>("https://api.altrabo.com/api/v1/token", tokenClient); // 替换.Result为await,避免死锁 var contentStr = await response.Content.ReadAsStringAsync(); var json = JsonSerializer.Deserialize<AccessToken>(contentStr); return json.access_token; }
3. 调整业务接口请求方法,添加授权头
public static async Task<string> ListAirports(string accessToken) { // 先清空避免重复添加,再写入授权头 _httpClient.DefaultRequestHeaders.Remove("Authorization"); _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken}"); return await _httpClient.GetStringAsync("https://api.altrabo.com/api/v1/BaseData/GetAirports?pageSize=1000&pageNumber=1"); }
4. 调用流程示例
// 程序启动先初始化配置 InitHttpClient(); // 获取访问令牌 var token = await getAccessToken(); // 校验令牌有效性(可选) var verifyResult = await verifyToken(token); if(verifyResult == "OK") { // 携带令牌调用业务接口 var airports = await ListAirports(token); }
内容的提问来源于stack exchange,提问作者MB_18
相关产品推荐
相关产品推荐

