xero api 在调用 getinvoices 时调用 auth、refresh 和 gettenants 后因未经授权(401 或 403)而失败

xero api fails with unauthorized (401 or 403) after calling auth, refresh and gettenants when calling getinvoices

我是这方面的菜鸟,请原谅我的无知。我有一个 MVC Web 应用程序可以登录、获取访问和刷新令牌,以及租户列表。我什至可以用它来刷新刷新令牌。没问题。

当我尝试直接或通过 sdk 运行 GetInvoices 端点时,我从直接 api 调用中得到 403 (skd) 或 401。

从最近的 运行 直接调用我得到了这个回复

{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: 
System.Net.Http.HttpConnectionResponseContent, Headers:
{
  Server: nginx
  Strict-Transport-Security: max-age=31536000
  WWW-Authenticate: OAuth Realm="api.xero.com"
  Cache-Control: no-store, no-cache, max-age=0
  Pragma: no-cache
  Date: Wed, 21 Jul 2021 11:19:56 GMT
  Connection: close
  X-Client-TLS-ver: tls1.2
  Content-Type: text/html; charset=utf-8
  Content-Length: 95
  Expires: Wed, 21 Jul 2021 11:19:56 GMT
}, Trailing Headers:
{
}}

我知道 GetInvoices 步骤中使用的访问令牌和租户 ID 是正确的,因为我根据从身份验证步骤中逐个字符提取的值检查了它们。

应用程序 运行 于 Visual Studio 2019 年,使用自签名开发 SSL 证书。

为什么拒绝请求?

我的控制器具有以下功能

private static readonly string Scopes = "openid offline_access 配置文件电子邮件 accounting.transactions accounting.contacts accounting.attachments";

        private static readonly string Scopes = "openid offline_access profile email accounting.transactions accounting.contacts accounting.attachments";

            string[] tenant = (string[])TempData.Peek("tenant");
        var client = new HttpClient();

        var formContent = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("summaryOnly", "true"),
        });

        client.DefaultRequestHeaders.Add("Authorization", (string)TempData.Peek("accessToken"));

        client.DefaultRequestHeaders.Add("Xero-Tenant-Id", tenant[0]);

        client.DefaultRequestHeaders.Add("Accept", "application/json");

        var response = await client.PostAsync("https://api.xero.com/api.xro/2.0/Invoices", formContent);

SDK 应该在客户端和 OAuth 流程的帮助程序方法中为您处理这个问题,但我在下面的原始 API 调用中包含了看起来缺少的内容。

核心 API 调用 - 看起来您需要在令牌前加上 Bearer 字符串。

Authorization: "Bearer " + access_token

如果您想使用 SDK,请注意有一个用于 OAuth 助手的子 Nuget 包,它将帮助您获得一个访问令牌,您需要将其传递给核心 api 调用。

https://github.com/XeroAPI/Xero-NetStandard/tree/master/Xero.NetStandard.OAuth2Client

(DOH!) 租户 return 有一个 Id 和一个 TenantId。我用的是 Id.

感谢 SerKnight 和 droopsnoot 的帮助。

我添加了来自 OAuth2 的代码。帮助没有提到获取和转换 return 类型的 RequestAcessTokenAsync。

    XeroOAuth2Token authToken = (XeroOAuth2Token)await client.RequestAccessTokenAsync(authorisationCode);

还要检查 return 上的状态,您必须在 xconfig 中设置。我读

    XeroConfiguration xconfig = new()
            {
                ClientId = Global.XeroClientID,
                ClientSecret = Global.XeroClientSecret,
                CallbackUri = new Uri(Global.RedirectURI),
                Scope = Global.XeroScopes,
                State = Global.XeroState
            };

            var client = new XeroClient(xconfig);

            return Redirect(client.BuildLoginUri());