Asana API C# 中的 403 响应
Asana API 403 Response in C#
我正在尝试实现与 Asana 一起使用的 Xamarin 应用 API。
我已经成功实施了 Asana 文档中记录的 OAuth here...至少我认为它是成功的。我从具有 HTTP 状态 "OK".
的 HTTPResponse 中的令牌端点获取访问令牌
但是当我转身并尝试使用相同的访问令牌进行 API 调用时,我收到 403 Forbidden 错误。我在我的浏览器中尝试了相同的 API 调用(登录 Asana 后),它工作正常,这让我相信我确实有权访问该资源,我必须在授权请求时遇到问题我的结局。
有问题的 API 调用是 (documented here): https://app.asana.com/api/1.0/workspaces.
我的C#代码如下(相关部分缩写,并假设ACCESS_TOKEN
包含我从令牌交换端点获得的访问令牌):
HttpClient client = new HttpClient();
client.BaseAddress = "https://app.asana.com/api/1.0";
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", ACCESS_TOKEN);
client.DefaultRequestHeaders.Add("Accept", "application/json");
然后我在以下函数中使用这个 HttpClient
(名为 client
):
// Returns a list of the Asana workspace names for the logged in user.
private async Task<List<string>> GetWorkspacesAsync()
{
List<string> namesList = new List<string>();
// Send the HTTP Request and get a response.
this.UpdateToken(); // Refreshes the token if needed using the refresh token.
using (HttpResponseMessage response = await client.GetAsync("/workspaces"))
{
// Handle a bad (not ok) response.
if (response.StatusCode != HttpStatusCode.OK)
{
// !!!THIS KEEPS TRIGGERING WITH response.StatusCode AS 403 Forbidden!!!
// Set up a stream reader to read the response.
// This is for TESTING ONLY
using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
{
// Extract the json object from the response.
string content = reader.ReadToEnd();
Debug.WriteLine(content);
}
throw new HttpRequestException("Bad HTTP Response was returned.");
}
// If execution reaches this point, the Http Response returned with code OK.
// Set up a stream reader to read the response.
using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
{
// Extract the json object from the response.
string content = reader.ReadToEnd();
JsonValue responseJson = JsonValue.Parse(content);
foreach (JsonValue workspaceJson in responseJson["data"])
{
string workspaceName = workspaceJson["name"];
Debug.WriteLine("Workspace Name: " + workspaceName);
namesList.Add(workspaceName);
}
}
}
// I have other awaited interactions with app storage in here, hence the need for the function to be async.
return namesList;
}
终于找到答案了。看来我使用 HttpClient
不正确;一个微妙的东西应该是等效的,但不是由于它的实现方式。
答案
我需要将最后一个斜杠放在 HttpClient
的 BaseAddress
属性 的末尾,而不是特定请求的相对地址的开头。 This answered question explains this.
修复我的代码
我需要更改 BaseAddress
的设置:
HttpClient client = new HttpClient();
client.BaseAddress = "https://app.asana.com/api/1.0/"; // FINAL SLASH NEEDED HERE
并从请求的相对地址中删除斜杠:
// DO NOT put slash before relative address "workspaces" here
using (HttpResponseMessage response = await client.GetAsync("workspaces"))
为什么我得到原来的错误
当 HttpClient
将 BaseAddress
与我在 GetAsync()
中指定的相对 URI 组合时,它丢弃了一些基址,因为最后的斜杠不包括在内。 BaseAddress
与相对 URI 组合的结果地址是有效的 URL,但在 Asana 中不是有效的 page/API 调用。因此,Asana 自动重定向到登录页面,当然,API 调用的其余部分将被禁止从那里进行。
我是怎么发现这个的
在调试过程中,我获取了我的应用在 Asana 授权期间返回的访问令牌。然后,我自己在 Postman 中重新创建了对“/workspaces”API 的请求,请求按预期工作。这证实我的授权工作正常,问题必须与特定请求有关,而不是授权。在调试过程中,我随后查看了 HttpResponseMessage
,它有一个名为 RequestMessage
的 属性,其中包括 GetAsync()
发出请求的实际 URL。我观察到来自 Asana 的登录名 URL,而不是我指定的 BaseAddress
...这让我想到了这个问题/
上面链接的答案。
希望这个解释对遇到类似错误的人有所帮助!
我正在尝试实现与 Asana 一起使用的 Xamarin 应用 API。
我已经成功实施了 Asana 文档中记录的 OAuth here...至少我认为它是成功的。我从具有 HTTP 状态 "OK".
的 HTTPResponse 中的令牌端点获取访问令牌但是当我转身并尝试使用相同的访问令牌进行 API 调用时,我收到 403 Forbidden 错误。我在我的浏览器中尝试了相同的 API 调用(登录 Asana 后),它工作正常,这让我相信我确实有权访问该资源,我必须在授权请求时遇到问题我的结局。
有问题的 API 调用是 (documented here): https://app.asana.com/api/1.0/workspaces.
我的C#代码如下(相关部分缩写,并假设ACCESS_TOKEN
包含我从令牌交换端点获得的访问令牌):
HttpClient client = new HttpClient();
client.BaseAddress = "https://app.asana.com/api/1.0";
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", ACCESS_TOKEN);
client.DefaultRequestHeaders.Add("Accept", "application/json");
然后我在以下函数中使用这个 HttpClient
(名为 client
):
// Returns a list of the Asana workspace names for the logged in user.
private async Task<List<string>> GetWorkspacesAsync()
{
List<string> namesList = new List<string>();
// Send the HTTP Request and get a response.
this.UpdateToken(); // Refreshes the token if needed using the refresh token.
using (HttpResponseMessage response = await client.GetAsync("/workspaces"))
{
// Handle a bad (not ok) response.
if (response.StatusCode != HttpStatusCode.OK)
{
// !!!THIS KEEPS TRIGGERING WITH response.StatusCode AS 403 Forbidden!!!
// Set up a stream reader to read the response.
// This is for TESTING ONLY
using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
{
// Extract the json object from the response.
string content = reader.ReadToEnd();
Debug.WriteLine(content);
}
throw new HttpRequestException("Bad HTTP Response was returned.");
}
// If execution reaches this point, the Http Response returned with code OK.
// Set up a stream reader to read the response.
using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
{
// Extract the json object from the response.
string content = reader.ReadToEnd();
JsonValue responseJson = JsonValue.Parse(content);
foreach (JsonValue workspaceJson in responseJson["data"])
{
string workspaceName = workspaceJson["name"];
Debug.WriteLine("Workspace Name: " + workspaceName);
namesList.Add(workspaceName);
}
}
}
// I have other awaited interactions with app storage in here, hence the need for the function to be async.
return namesList;
}
终于找到答案了。看来我使用 HttpClient
不正确;一个微妙的东西应该是等效的,但不是由于它的实现方式。
答案
我需要将最后一个斜杠放在 HttpClient
的 BaseAddress
属性 的末尾,而不是特定请求的相对地址的开头。 This answered question explains this.
修复我的代码
我需要更改 BaseAddress
的设置:
HttpClient client = new HttpClient();
client.BaseAddress = "https://app.asana.com/api/1.0/"; // FINAL SLASH NEEDED HERE
并从请求的相对地址中删除斜杠:
// DO NOT put slash before relative address "workspaces" here
using (HttpResponseMessage response = await client.GetAsync("workspaces"))
为什么我得到原来的错误
当 HttpClient
将 BaseAddress
与我在 GetAsync()
中指定的相对 URI 组合时,它丢弃了一些基址,因为最后的斜杠不包括在内。 BaseAddress
与相对 URI 组合的结果地址是有效的 URL,但在 Asana 中不是有效的 page/API 调用。因此,Asana 自动重定向到登录页面,当然,API 调用的其余部分将被禁止从那里进行。
我是怎么发现这个的
在调试过程中,我获取了我的应用在 Asana 授权期间返回的访问令牌。然后,我自己在 Postman 中重新创建了对“/workspaces”API 的请求,请求按预期工作。这证实我的授权工作正常,问题必须与特定请求有关,而不是授权。在调试过程中,我随后查看了 HttpResponseMessage
,它有一个名为 RequestMessage
的 属性,其中包括 GetAsync()
发出请求的实际 URL。我观察到来自 Asana 的登录名 URL,而不是我指定的 BaseAddress
...这让我想到了这个问题/
上面链接的答案。
希望这个解释对遇到类似错误的人有所帮助!