我只需要使用带有C#的API来访问我的Quickbooks Online(QBO)公司中的数据。但是现在他们已经迁移到OAuth2,它看起来非常复杂。例如,它建议我需要一个重定向URI来接收授权代码,但是我正在编写一个简单的控制台应用程序以将数据导出到QBO,并且不想托管一个URI端点来这样做。
知道如何获取和管理以下内容也令人困惑:
必须有一种简单的方法来执行此操作。例如,使用Stripe,您只需管理一个API密钥。
答案 0 :(得分:0)
经过一些研究,我发现这可以通过简单的方式完成。您只需要保留刷新令牌的副本(也许在读/写文件中)。当您要访问API时,只需调用OAuth2Client.RefreshTokenAsync()即可获取访问令牌。其他所有必需项都可以在OAuth2游乐场中找到。
然后,访问令牌可以与API一起使用长达一小时。您还可以取回更新的刷新令牌。如果发生这种情况,请将其存储以备将来使用。在您必须使用从“刷新令牌”操作返回的较新版本之前,刷新令牌持续长达100天。
有关如何使用C#中的API的较长版本:
创建一个应用,但不要在QBO应用商店中发布。为此登录 使用您的QBO帐户的developer.intuit.com。转到“我的应用”,然后创建一个应用(例如,名为“ MyQBOApiApp ”)。这仅需要执行一次。将默认重定向URL设置为OAuth2游乐场,因为这是唯一需要的重定向URL。
从“ OAuth 2.0密钥”标签的“生产密钥”部分获取应用的生产客户端ID 和客户端密钥。 (将它们记录下来,以便在C#程序中使用,因为它们不会更改)
转到https://developer.intuit.com/v2/ui#/playground的OAuth 2.0游乐场
在步骤1“获取授权码”中,从下拉列表框中选择MyQBOApiApp(Production)
如果您只需要向QBO公司读取/写入数据,请在“选择范围”列表中选择“会计”
点击“获取授权码”
将您的QBO公司连接到MyQBOApiApp应用
在操场上页面的第2步“从身份验证代码获取OAuth 2.0令牌”中,点击“获取令牌” 。这将为您对公司的API访问获得刷新令牌。
跳到游乐场页面上的第4步“刷新访问令牌”。访问令牌只能使用59分钟 因此只需保留“刷新令牌” ,因为它可以使用100天来获取新的访问令牌和刷新令牌。将其存储在您的C#程序可以读取和写入的位置(例如文件或数据库)
领域ID 可从步骤3中获得。“进行API调用”。 (将其记录下来,以便在C#程序中使用,因为它不会更改)
将IppDotNetSdkForQuickBooksApiV3 NuGet程序包添加到C#程序中。为了提供对API的轻松访问。
确保您使用的是.Net Framework 4.6.1或更高版本,因为QBO需要TLS 1.2连接
不幸的是,.Net控制台应用程序默认情况下不使用TLS 1.2。因此,请将这行代码添加到C#程序的启动位置:
// Have to explicitly set TLS 1.2 as QBO APIs require it
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
在访问API之前,您将需要以下代码来获取访问令牌:
public static string GetAccessToken()
{
var oauth2Client = new OAuth2Client(CLIENTID_FROM_STEP_2,
CLIENT_SECRET_FROM_STEP_2,
// Redirect not used but matches entry for app
"https://developer.intuit.com/v2/OAuth2Playground/RedirectUrl",
"production"); // environment is “sandbox” or “production”
var previousRefreshToken = ReadRefreshTokenFromWhereItIsStored();
var tokenResp = oauth2Client.RefreshTokenAsync(previousRefreshToken );
tokenResp.Wait();
var data = tokenResp.Result;
if ( !String.IsNullOrEmpty(data.Error) || String.IsNullOrEmpty(data.RefreshToken) ||
String.IsNullOrEmpty(data.AccessToken))
{
throw new Exception("Refresh token failed - " + data.Error);
}
// If we've got a new refresh_token store it in the file
if (previousRefreshToken != data.RefreshToken)
{
Console.WriteLine("Writing new refresh token : " + data.RefreshToken);
WriteNewRefreshTokenToWhereItIsStored(data.RefreshToken)
}
return data.AccessToken;
}
您需要编写函数 ReadRefreshTokenFromWhereItIsStored()和 WriteNewRefreshTokenToWhereItIsStored(),以从持久性存储中加载和保存刷新令牌。
QBO中的所有API访问均始于服务上下文。您可以使用以下代码创建一个代码:
static public ServiceContext GetServiceContext()
{
var accessToken = GetAccessToken(); // Code from above
var oauthValidator = new OAuth2RequestValidator(accessToken);
ServiceContext qboContext = new ServiceContext(REALMID_PROD_FROM_STEP10,
IntuitServicesType.QBO, oauthValidator);
return qboContext;
}
要访问数据,您可以创建数据服务,如下所示:
var service = new DataService(GetServiceContext());
答案 1 :(得分:0)
[HttpPost("qb/refresh-token")]
public async Task<ActionResult> GetRefressToken()
{
JObject result = new JObject();
//Request Oauth2 tokens
var tokenClient = new OAuth2Client(
"your client id",
"secret",
"https://developer.intuit.com/v2/OAuth2Playground/RedirectUrl",
"sandbox"); // environment is “sandbox” or “production”
var previousRefreshToken = "your refresh token id ";Get it from Playgroud for first time**strong text**//ReadRefreshTokenFromWhereItIsStored();
var tokenResp = await tokenClient.RefreshTokenAsync(previousRefreshToken);
if (!String.IsNullOrEmpty(tokenResp.Error) || String.IsNullOrEmpty(tokenResp.RefreshToken) ||
String.IsNullOrEmpty(tokenResp.AccessToken))
{
throw new Exception("Refresh token failed - " + tokenResp.Error);
}
// If we've got a new refresh_token store it in the file
if (previousRefreshToken != tokenResp.RefreshToken)
{
Console.WriteLine("Writing new refresh token : " + tokenResp.RefreshToken);
//WriteNewRefreshTokenToWhereItIsStored(data.RefreshToken);
}
return Ok(tokenResp.AccessToken);
//return new Tuple<string, string>(tokenResp.RefreshToken, tokenResp.AccessToken);
}