QBO API 在同一步骤中连接和授权
QBO API Connect and Authorize in the same step
我正在使用 QBO API SDK (IppDotNetSdkQuickBooksApiV3),但不知道如何让用户连接到 QuickBooks 并授权我的应用程序。它目前分两 (2) 个步骤进行:
- 用户点击 "Connect To Intuit" 并被发送到 Intuit 进行登录
- 他们被重定向回我的应用程序,然后必须再次连接他们的实际文件
我显然遗漏了什么,但不知道是什么。我正在使用应用程序内置的 ipp:connecttointuit 功能,所以我不知道如何针对我正在寻找的结果对其进行自定义。
我的应用程序可以通过上述两个步骤运行,但是我无法使用上面详述的过程将我的应用程序列在 apps.com 网站中。他们 (apps.com) 希望用户使用他们的 QBO 凭据登录,授权应用程序,然后自动将用户重定向回我的网站,应用程序正常运行。他们不想要重复授权(我不能怪他们)。
完全卡住了。我是一个不错的程序员,但没有使用 OpenId 或 OAuth 的经验。
protected void Page_Load(object sender, EventArgs e)
{
var openIdRelyingParty = new OpenIdRelyingParty();
var openid_identifier = ConfigurationManager.AppSettings["openid_identifier"];
var returnUrl = "~/OpenID/Connect";
var response = openIdRelyingParty.GetResponse();
if (response == null)
{
// Stage 2: user submitting Identifier
Identifier id;
if (Identifier.TryParse(openid_identifier, out id))
{
IAuthenticationRequest request = openIdRelyingParty.CreateRequest(openid_identifier);
FetchRequest fetch = new FetchRequest();
fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email));
fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.FullName));
fetch.Attributes.Add(new AttributeRequest("http://axschema.org/intuit/realmId"));
request.AddExtension(fetch);
request.RedirectToProvider();
}
}
else
{
if (response.FriendlyIdentifierForDisplay == null)
{
Response.Redirect("~/OpenID/Connect");
}
// Stage 3: OpenID Provider sending assertion response
//Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
FetchResponse fetch = response.GetExtension<FetchResponse>();
if (fetch != null)
{
var openIdEmail = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);
var openIdFullName = fetch.GetAttributeValue(WellKnownAttributes.Name.FullName);
var openIdRealmId = fetch.GetAttributeValue("http://axschema.org/intuit/realmId");
string userName = Membership.GetUserNameByEmail(openIdEmail);
//If username is null---------------------------------------------------
if (userName == null)
{
//DG added this---------------------------
String NewPassword = Membership.GeneratePassword(6, 1);
Membership.CreateUser(openIdEmail, NewPassword, openIdEmail);
//DG added this----------------------------
//Membership.CreateUser(openIdEmail, Guid.NewGuid().ToString(), openIdEmail);
FormsAuthentication.SetAuthCookie(openIdEmail, true);
//if (Request.QueryString["Subscribe"] != null)
//{
String csname = "DirectConnectScript";
Type cstype = this.GetType();
ClientScriptManager csm = Page.ClientScript;
// Check to see if the startup script is already registered.
if (!csm.IsStartupScriptRegistered(cstype, csname))
{
StringBuilder cstext = new StringBuilder();
cstext.AppendLine("<script>");
cstext.AppendLine("$(document).ready(function () {");
cstext.AppendLine("intuit.ipp.anywhere.directConnectToIntuit();");
cstext.AppendLine("});");
cstext.AppendLine("</script>");
csm.RegisterStartupScript(cstype, csname, cstext.ToString());
//}
}
}
else if (Request.QueryString["Disconnect"] != null)
{
RestHelper.clearProfile(RestProfile.GetRestProfile());
Response.Redirect("~/ManageConnection");
}
//If username is not null---------------------------------------------------
else if (userName != null)
{
FormsAuthentication.SetAuthCookie(userName, true);
if (!string.IsNullOrEmpty(returnUrl))
{
Response.Redirect("~/ManageConnection");
}
}
}
}
}
我同情你,我自己花了一些时间才搞定。
这是我的 MVC 版本。希望对你有帮助。
它以 QuickBooks/Index 开头。使用 QB 弹出窗口获取我的应用程序的权限,然后从那里开始。作为奖励,如果用户已经登录到 QB,如果他们在过去授予权限,他们将自动登录到该应用程序。这是因为我将加密的令牌保存在数据库中。 (忽略大部分 Session 内容,我只是从未将其从我创建代码的示例中删除)。
不管怎样,这里有很多 post 的代码。
如果您需要任何说明,请随时在评论中提问
我假设你有这样的东西接收 OAuthResponse 并重定向回 /QuickBooks/Index(在你的情况下,你在问题中 posted 的页面)
public class OauthResponseController : Controller
{
/// <summary>
/// OAuthVerifyer, RealmId, DataSource
/// </summary>
private String _oauthVerifyer, _realmid, _dataSource;
/// <summary>
/// Action Results for Index, OAuthToken, OAuthVerifyer and RealmID is recieved as part of Response
/// and are stored inside Session object for future references
/// NOTE: Session storage is only used for demonstration purpose only.
/// </summary>
/// <returns>View Result.</returns>
public ViewResult Index()
{
if (Request.QueryString.HasKeys())
{
// This value is used to Get Access Token.
_oauthVerifyer = Request.QueryString.GetValues("oauth_verifier").FirstOrDefault().ToString();
if (_oauthVerifyer.Length == 1)
{
_oauthVerifyer = Request.QueryString["oauth_verifier"].ToString();
}
_realmid = Request.QueryString.GetValues("realmId").FirstOrDefault().ToString();
if (_realmid.Length == 1)
{
_realmid = Request.QueryString["realmId"].ToString();
}
Session["Realm"] = _realmid;
//If dataSource is QBO call QuickBooks Online Services, else call QuickBooks Desktop Services
_dataSource = Request.QueryString.GetValues("dataSource").FirstOrDefault().ToString();
if (_dataSource.Length == 1)
{
_dataSource = Request.QueryString["dataSource"].ToString();
}
Session["DataSource"] = _dataSource;
getAccessToken();
//Production applications should securely store the Access Token.
//In this template, encrypted Oauth access token is persisted in OauthAccessTokenStorage.xml
OauthAccessTokenStorageHelper.StoreOauthAccessToken();
// This value is used to redirect to Default.aspx from Cleanup page when user clicks on ConnectToInuit widget.
Session["RedirectToDefault"] = true;
}
else
{
Response.Write("No oauth token was received");
}
return View(); // This will redirect to /QuickBooks/OpenIdIndex which is almost the same as the code that you have posted
}
/// <summary>
/// Gets the OAuth Token
/// </summary>
private void getAccessToken()
{
IOAuthSession clientSession = CreateSession();
try
{
IToken accessToken = clientSession.ExchangeRequestTokenForAccessToken((IToken)Session["requestToken"], _oauthVerifyer);
Session["AccessToken"] = accessToken.Token;
// Add flag to session which tells that accessToken is in session
Session["Flag"] = true;
// Remove the Invalid Access token since we got the new access token
Session.Remove("InvalidAccessToken");
Session["AccessTokenSecret"] = accessToken.TokenSecret;
}
catch (Exception ex)
{
//Handle Exception if token is rejected or exchange of Request Token for Access Token failed.
throw ex;
}
}
/// <summary>
/// Creates User Session
/// </summary>
/// <returns>OAuth Session.</returns>
private IOAuthSession CreateSession()
{
OAuthConsumerContext consumerContext = new OAuthConsumerContext
{
ConsumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString(),
ConsumerSecret = ConfigurationManager.AppSettings["consumerSecret"].ToString(),
SignatureMethod = SignatureMethod.HmacSha1
};
return new OAuthSession(consumerContext,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlRequestToken,
Constants.OauthEndPoints.IdFedOAuthBaseUrl,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlAccessToken);
}
}
这是我的对应页面。
public class QuickBooksController : Controller
{
private readonly IQueryChannel _queryChannel;
private readonly ICommandChannel _commandChannel;
public QuickBooksController(IQueryChannel queryChannel, ICommandChannel commandChannel)
{
_queryChannel = queryChannel;
_commandChannel = commandChannel;
}
/// <summary>
/// OpenId Relying Party
/// </summary>
private static OpenIdRelyingParty openid = new OpenIdRelyingParty();
public ActionResult Index(string returnurl)
{
QuickBooksAuthStore.Load();
if (QuickBooksContext.AccessToken != null)
{
if (!new Customers().CheckConnection())
{
QuickBooksContext.FriendlyName = null;
OauthAccessTokenStorageHelper.RemoveInvalidOauthAccessToken(QuickBooksContext.FriendlyEmail);
QuickBooksContext.AccessToken = null;
}
}
if (returnurl != null || QuickBooksContext.QuickReturnUrl != null)
{
if (returnurl != null)
{
QuickBooksContext.QuickReturnUrl = returnurl;
}
if (QuickBooksContext.AccessToken != null)
{
var connected = new Customers().CheckConnection();
if (connected)
{
returnurl = QuickBooksContext.QuickReturnUrl;
QuickBooksContext.QuickReturnUrl = null;
return Redirect(returnurl);
}
}
}
return View();
}
public RedirectResult OpenIdIndex()
{
var openid_identifier = ConfigurationManager.AppSettings["openid_identifier"] + SessionContext.CurrentUser.MasterCompanyId;
var response = openid.GetResponse();
if (response == null)
{
// Stage 2: user submitting Identifier
Identifier id;
if (Identifier.TryParse(openid_identifier, out id))
{
try
{
IAuthenticationRequest request = openid.CreateRequest(openid_identifier);
FetchRequest fetch = new FetchRequest();
fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email));
fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.FullName));
request.AddExtension(fetch);
request.RedirectToProvider();
}
catch (ProtocolException ex)
{
throw ex;
}
}
}
else
{
if (response.FriendlyIdentifierForDisplay == null)
{
Response.Redirect("/OpenId");
}
// Stage 3: OpenID Provider sending assertion response, storing the response in Session object is only for demonstration purpose
Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
FetchResponse fetch = response.GetExtension<FetchResponse>();
if (fetch != null)
{
Session["OpenIdResponse"] = "True";
Session["FriendlyEmail"] = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);// emailAddresses.Count > 0 ? emailAddresses[0] : null;
Session["FriendlyName"] = fetch.GetAttributeValue(WellKnownAttributes.Name.FullName);//fullNames.Count > 0 ? fullNames[0] : null;
OauthAccessTokenStorageHelper.GetOauthAccessTokenForUser(Session["FriendlyEmail"].ToString());
QuickBooksAuthStore.UpdateFriendlyId(Session["FriendlyIdentifier"].ToString(), Session["FriendlyName"].ToString());
}
}
string query = Request.Url.Query;
if (!string.IsNullOrWhiteSpace(query) && query.ToLower().Contains("disconnect=true"))
{
Session["AccessToken"] = "dummyAccessToken";
Session["AccessTokenSecret"] = "dummyAccessTokenSecret";
Session["Flag"] = true;
return Redirect("QuickBooks/CleanupOnDisconnect");
}
return Redirect("/QuickBooks/Index");
}
/// <summary>
/// Service response.
/// </summary>
private String txtServiceResponse = "";
/// <summary>
/// Disconnect Flag.
/// </summary>
protected String DisconnectFlg = "";
public ActionResult Disconnect()
{
OAuthConsumerContext consumerContext = new OAuthConsumerContext
{
ConsumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString(),
SignatureMethod = SignatureMethod.HmacSha1,
ConsumerSecret = ConfigurationManager.AppSettings["consumerSecret"].ToString()
};
OAuthSession oSession = new OAuthSession(consumerContext, Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlRequestToken,
Constants.OauthEndPoints.AuthorizeUrl,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlAccessToken);
oSession.ConsumerContext.UseHeaderForOAuthParameters = true;
if ((Session["AccessToken"] + "").Length > 0)
{
Session["FriendlyName"] = null;
oSession.AccessToken = new TokenBase
{
Token = Session["AccessToken"].ToString(),
ConsumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString(),
TokenSecret = Session["AccessTokenSecret"].ToString()
};
IConsumerRequest conReq = oSession.Request();
conReq = conReq.Get();
conReq = conReq.ForUrl(Constants.IaEndPoints.DisconnectUrl);
try
{
conReq = conReq.SignWithToken();
}
catch (Exception ex)
{
throw ex;
}
//Used just see the what header contains
string header = conReq.Context.GenerateOAuthParametersForHeader();
//This method will clean up the OAuth Token
txtServiceResponse = conReq.ReadBody();
//Reset All the Session Variables
Session.Remove("oauthToken");
// Dont remove the access token since this is required for Reconnect btn in the Blue dot menu
// Session.Remove("accessToken");
// Add the invalid access token into session for the display of the Disconnect btn
Session["InvalidAccessToken"] = Session["AccessToken"];
// Dont Remove flag since we need to display the blue dot menu for Reconnect btn in the Blue dot menu
// Session.Remove("Flag");
ViewBag.DisconnectFlg = "User is Disconnected from QuickBooks!";
//Remove the Oauth access token from the OauthAccessTokenStorage.xml
OauthAccessTokenStorageHelper.RemoveInvalidOauthAccessToken(Session["FriendlyEmail"].ToString());
}
return RedirectToAction("Index", "QuickBooks");
}
public ActionResult CleanUpOnDisconnect()
{
//perform the clean up here
// Redirect to Home when user clicks on ConenctToIntuit widget.
object value = Session["RedirectToDefault"];
if (value != null)
{
bool isTrue = (bool)value;
if (isTrue)
{
Session.Remove("InvalidAccessToken");
Session.Remove("RedirectToDefault");
return Redirect("/QuickBooks/index");
}
}
return RedirectToAction("Index", "QuickBooks");
}
private String consumerSecret, consumerKey, oauthLink, RequestToken, TokenSecret, oauth_callback_url;
public RedirectResult OAuthGrant()
{
oauth_callback_url = Request.Url.GetLeftPart(UriPartial.Authority) + ConfigurationManager.AppSettings["oauth_callback_url"];
consumerKey = ConfigurationManager.AppSettings["consumerKey"];
consumerSecret = ConfigurationManager.AppSettings["consumerSecret"];
oauthLink = Constants.OauthEndPoints.IdFedOAuthBaseUrl;
IToken token = (IToken)Session["requestToken"];
IOAuthSession session = CreateSession();
IToken requestToken = session.GetRequestToken();
Session["requestToken"] = requestToken;
RequestToken = requestToken.Token;
TokenSecret = requestToken.TokenSecret;
oauthLink = Constants.OauthEndPoints.AuthorizeUrl + "?oauth_token=" + RequestToken + "&oauth_callback=" + UriUtility.UrlEncode(oauth_callback_url);
return Redirect(oauthLink);
}
/// <summary>
/// Gets the Access Token
/// </summary>
/// <returns>Returns OAuth Session</returns>
protected IOAuthSession CreateSession()
{
OAuthConsumerContext consumerContext = new OAuthConsumerContext
{
ConsumerKey = consumerKey,
ConsumerSecret = consumerSecret,
SignatureMethod = SignatureMethod.HmacSha1
};
return new OAuthSession(consumerContext,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlRequestToken,
oauthLink,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlAccessToken);
}
}
..这里是 QuickBooks/Index
的 cshtml 页面
@using System.Configuration
@using PubManager.Domain.WebSession
@{
string MenuProxy = Request.Url.GetLeftPart(UriPartial.Authority) + "/" + System.Configuration.ConfigurationManager.AppSettings["menuProxy"];
string OauthGrant = Request.Url.GetLeftPart(UriPartial.Authority) + "/" + System.Configuration.ConfigurationManager.AppSettings["grantUrl"];
ViewBag.Title = "MagManager - Intuit Anywhere";
string FriendlyName = (string)HttpContext.Current.Session["FriendlyName"] + "";
string FriendlyEmail = (string)HttpContext.Current.Session["FriendlyEmail"];
string FriendlyIdentifier = (string)HttpContext.Current.Session["FriendlyIdentifier"];
string realm = (string)Session["Realm"];
string dataSource = (string)Session["DataSource"];
string accessToken = (string)Session["AccessToken"] + "";
string accessTokenSecret = (string)Session["AccessTokenSecret"];
string invalidAccessToken = (string)Session["InvalidAccessToken"];
}
<h1>Intuit - QuickBooks Online</h1>
<div class="well">
@if (FriendlyName.Length == 0)
{
<script>
window.location.href = "/QuickBooks/OpenIdIndex";
</script>
}
else
{
<div id="IntuitInfo">
<strong>Open Id Information:</strong><br />
Welcome: @FriendlyName<br />
E-mail Address: @FriendlyEmail<br />
<br />
@if (accessToken.Length > 0 && invalidAccessToken == null)
{
<div id="oAuthinfo">
<a onclick="reconcileInvoices()" id="RecInvoices" class="btn btn-primary">Set Invoices Paid</a><br />
<br/>
<a onclick="recTax()" id="RecTax" class="btn btn-primary">Sync Tax Rates</a><br />
<br/>
@if (SessionContext.UseAccountCodes)
{
<a onclick="recProducts()" id="RecProducts" class="btn btn-primary">Sync Products</a><br />
<br />
}
<a href="/QuickBooks/ReconcileCustomers" id="Customers" class="btn btn-primary">Reconcile Customers</a><br/>
<br/>
<a href="/QuickBooks/Disconnect" id="Disconnect" class="btn btn-primary">
Disconnect from
QuickBooks
</a>
<br/><br/>
@*<a href="/QuickBooks/Customers" id="QBCustomers" class="btn btn-primary">Get QuickBooks Customer List</a><br/>
<br/>*@
@*<br />
<a href="/QuickBooks/Invoices" id="QBInvoices" class="btn btn-primary">Get QuickBooks Invoice List</a><br />
<br />*@
<br />
</div>
}
else
{
<br />
<ipp:connecttointuit></ipp:connecttointuit>
}
</div>
}
</div>
<script type="text/javascript" src="https://js.appcenter.intuit.com/Content/IA/intuit.ipp.anywhere-1.3.5.js"></script>
<script type="text/javascript">
intuit.ipp.anywhere.setup({
menuProxy: '@MenuProxy',
grantUrl: '@OauthGrant'
});
</script>
我正在使用 QBO API SDK (IppDotNetSdkQuickBooksApiV3),但不知道如何让用户连接到 QuickBooks 并授权我的应用程序。它目前分两 (2) 个步骤进行:
- 用户点击 "Connect To Intuit" 并被发送到 Intuit 进行登录
- 他们被重定向回我的应用程序,然后必须再次连接他们的实际文件
我显然遗漏了什么,但不知道是什么。我正在使用应用程序内置的 ipp:connecttointuit 功能,所以我不知道如何针对我正在寻找的结果对其进行自定义。
我的应用程序可以通过上述两个步骤运行,但是我无法使用上面详述的过程将我的应用程序列在 apps.com 网站中。他们 (apps.com) 希望用户使用他们的 QBO 凭据登录,授权应用程序,然后自动将用户重定向回我的网站,应用程序正常运行。他们不想要重复授权(我不能怪他们)。
完全卡住了。我是一个不错的程序员,但没有使用 OpenId 或 OAuth 的经验。
protected void Page_Load(object sender, EventArgs e)
{
var openIdRelyingParty = new OpenIdRelyingParty();
var openid_identifier = ConfigurationManager.AppSettings["openid_identifier"];
var returnUrl = "~/OpenID/Connect";
var response = openIdRelyingParty.GetResponse();
if (response == null)
{
// Stage 2: user submitting Identifier
Identifier id;
if (Identifier.TryParse(openid_identifier, out id))
{
IAuthenticationRequest request = openIdRelyingParty.CreateRequest(openid_identifier);
FetchRequest fetch = new FetchRequest();
fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email));
fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.FullName));
fetch.Attributes.Add(new AttributeRequest("http://axschema.org/intuit/realmId"));
request.AddExtension(fetch);
request.RedirectToProvider();
}
}
else
{
if (response.FriendlyIdentifierForDisplay == null)
{
Response.Redirect("~/OpenID/Connect");
}
// Stage 3: OpenID Provider sending assertion response
//Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
FetchResponse fetch = response.GetExtension<FetchResponse>();
if (fetch != null)
{
var openIdEmail = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);
var openIdFullName = fetch.GetAttributeValue(WellKnownAttributes.Name.FullName);
var openIdRealmId = fetch.GetAttributeValue("http://axschema.org/intuit/realmId");
string userName = Membership.GetUserNameByEmail(openIdEmail);
//If username is null---------------------------------------------------
if (userName == null)
{
//DG added this---------------------------
String NewPassword = Membership.GeneratePassword(6, 1);
Membership.CreateUser(openIdEmail, NewPassword, openIdEmail);
//DG added this----------------------------
//Membership.CreateUser(openIdEmail, Guid.NewGuid().ToString(), openIdEmail);
FormsAuthentication.SetAuthCookie(openIdEmail, true);
//if (Request.QueryString["Subscribe"] != null)
//{
String csname = "DirectConnectScript";
Type cstype = this.GetType();
ClientScriptManager csm = Page.ClientScript;
// Check to see if the startup script is already registered.
if (!csm.IsStartupScriptRegistered(cstype, csname))
{
StringBuilder cstext = new StringBuilder();
cstext.AppendLine("<script>");
cstext.AppendLine("$(document).ready(function () {");
cstext.AppendLine("intuit.ipp.anywhere.directConnectToIntuit();");
cstext.AppendLine("});");
cstext.AppendLine("</script>");
csm.RegisterStartupScript(cstype, csname, cstext.ToString());
//}
}
}
else if (Request.QueryString["Disconnect"] != null)
{
RestHelper.clearProfile(RestProfile.GetRestProfile());
Response.Redirect("~/ManageConnection");
}
//If username is not null---------------------------------------------------
else if (userName != null)
{
FormsAuthentication.SetAuthCookie(userName, true);
if (!string.IsNullOrEmpty(returnUrl))
{
Response.Redirect("~/ManageConnection");
}
}
}
}
}
我同情你,我自己花了一些时间才搞定。
这是我的 MVC 版本。希望对你有帮助。
它以 QuickBooks/Index 开头。使用 QB 弹出窗口获取我的应用程序的权限,然后从那里开始。作为奖励,如果用户已经登录到 QB,如果他们在过去授予权限,他们将自动登录到该应用程序。这是因为我将加密的令牌保存在数据库中。 (忽略大部分 Session 内容,我只是从未将其从我创建代码的示例中删除)。
不管怎样,这里有很多 post 的代码。 如果您需要任何说明,请随时在评论中提问
我假设你有这样的东西接收 OAuthResponse 并重定向回 /QuickBooks/Index(在你的情况下,你在问题中 posted 的页面)
public class OauthResponseController : Controller
{
/// <summary>
/// OAuthVerifyer, RealmId, DataSource
/// </summary>
private String _oauthVerifyer, _realmid, _dataSource;
/// <summary>
/// Action Results for Index, OAuthToken, OAuthVerifyer and RealmID is recieved as part of Response
/// and are stored inside Session object for future references
/// NOTE: Session storage is only used for demonstration purpose only.
/// </summary>
/// <returns>View Result.</returns>
public ViewResult Index()
{
if (Request.QueryString.HasKeys())
{
// This value is used to Get Access Token.
_oauthVerifyer = Request.QueryString.GetValues("oauth_verifier").FirstOrDefault().ToString();
if (_oauthVerifyer.Length == 1)
{
_oauthVerifyer = Request.QueryString["oauth_verifier"].ToString();
}
_realmid = Request.QueryString.GetValues("realmId").FirstOrDefault().ToString();
if (_realmid.Length == 1)
{
_realmid = Request.QueryString["realmId"].ToString();
}
Session["Realm"] = _realmid;
//If dataSource is QBO call QuickBooks Online Services, else call QuickBooks Desktop Services
_dataSource = Request.QueryString.GetValues("dataSource").FirstOrDefault().ToString();
if (_dataSource.Length == 1)
{
_dataSource = Request.QueryString["dataSource"].ToString();
}
Session["DataSource"] = _dataSource;
getAccessToken();
//Production applications should securely store the Access Token.
//In this template, encrypted Oauth access token is persisted in OauthAccessTokenStorage.xml
OauthAccessTokenStorageHelper.StoreOauthAccessToken();
// This value is used to redirect to Default.aspx from Cleanup page when user clicks on ConnectToInuit widget.
Session["RedirectToDefault"] = true;
}
else
{
Response.Write("No oauth token was received");
}
return View(); // This will redirect to /QuickBooks/OpenIdIndex which is almost the same as the code that you have posted
}
/// <summary>
/// Gets the OAuth Token
/// </summary>
private void getAccessToken()
{
IOAuthSession clientSession = CreateSession();
try
{
IToken accessToken = clientSession.ExchangeRequestTokenForAccessToken((IToken)Session["requestToken"], _oauthVerifyer);
Session["AccessToken"] = accessToken.Token;
// Add flag to session which tells that accessToken is in session
Session["Flag"] = true;
// Remove the Invalid Access token since we got the new access token
Session.Remove("InvalidAccessToken");
Session["AccessTokenSecret"] = accessToken.TokenSecret;
}
catch (Exception ex)
{
//Handle Exception if token is rejected or exchange of Request Token for Access Token failed.
throw ex;
}
}
/// <summary>
/// Creates User Session
/// </summary>
/// <returns>OAuth Session.</returns>
private IOAuthSession CreateSession()
{
OAuthConsumerContext consumerContext = new OAuthConsumerContext
{
ConsumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString(),
ConsumerSecret = ConfigurationManager.AppSettings["consumerSecret"].ToString(),
SignatureMethod = SignatureMethod.HmacSha1
};
return new OAuthSession(consumerContext,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlRequestToken,
Constants.OauthEndPoints.IdFedOAuthBaseUrl,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlAccessToken);
}
}
这是我的对应页面。
public class QuickBooksController : Controller
{
private readonly IQueryChannel _queryChannel;
private readonly ICommandChannel _commandChannel;
public QuickBooksController(IQueryChannel queryChannel, ICommandChannel commandChannel)
{
_queryChannel = queryChannel;
_commandChannel = commandChannel;
}
/// <summary>
/// OpenId Relying Party
/// </summary>
private static OpenIdRelyingParty openid = new OpenIdRelyingParty();
public ActionResult Index(string returnurl)
{
QuickBooksAuthStore.Load();
if (QuickBooksContext.AccessToken != null)
{
if (!new Customers().CheckConnection())
{
QuickBooksContext.FriendlyName = null;
OauthAccessTokenStorageHelper.RemoveInvalidOauthAccessToken(QuickBooksContext.FriendlyEmail);
QuickBooksContext.AccessToken = null;
}
}
if (returnurl != null || QuickBooksContext.QuickReturnUrl != null)
{
if (returnurl != null)
{
QuickBooksContext.QuickReturnUrl = returnurl;
}
if (QuickBooksContext.AccessToken != null)
{
var connected = new Customers().CheckConnection();
if (connected)
{
returnurl = QuickBooksContext.QuickReturnUrl;
QuickBooksContext.QuickReturnUrl = null;
return Redirect(returnurl);
}
}
}
return View();
}
public RedirectResult OpenIdIndex()
{
var openid_identifier = ConfigurationManager.AppSettings["openid_identifier"] + SessionContext.CurrentUser.MasterCompanyId;
var response = openid.GetResponse();
if (response == null)
{
// Stage 2: user submitting Identifier
Identifier id;
if (Identifier.TryParse(openid_identifier, out id))
{
try
{
IAuthenticationRequest request = openid.CreateRequest(openid_identifier);
FetchRequest fetch = new FetchRequest();
fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email));
fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.FullName));
request.AddExtension(fetch);
request.RedirectToProvider();
}
catch (ProtocolException ex)
{
throw ex;
}
}
}
else
{
if (response.FriendlyIdentifierForDisplay == null)
{
Response.Redirect("/OpenId");
}
// Stage 3: OpenID Provider sending assertion response, storing the response in Session object is only for demonstration purpose
Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
FetchResponse fetch = response.GetExtension<FetchResponse>();
if (fetch != null)
{
Session["OpenIdResponse"] = "True";
Session["FriendlyEmail"] = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);// emailAddresses.Count > 0 ? emailAddresses[0] : null;
Session["FriendlyName"] = fetch.GetAttributeValue(WellKnownAttributes.Name.FullName);//fullNames.Count > 0 ? fullNames[0] : null;
OauthAccessTokenStorageHelper.GetOauthAccessTokenForUser(Session["FriendlyEmail"].ToString());
QuickBooksAuthStore.UpdateFriendlyId(Session["FriendlyIdentifier"].ToString(), Session["FriendlyName"].ToString());
}
}
string query = Request.Url.Query;
if (!string.IsNullOrWhiteSpace(query) && query.ToLower().Contains("disconnect=true"))
{
Session["AccessToken"] = "dummyAccessToken";
Session["AccessTokenSecret"] = "dummyAccessTokenSecret";
Session["Flag"] = true;
return Redirect("QuickBooks/CleanupOnDisconnect");
}
return Redirect("/QuickBooks/Index");
}
/// <summary>
/// Service response.
/// </summary>
private String txtServiceResponse = "";
/// <summary>
/// Disconnect Flag.
/// </summary>
protected String DisconnectFlg = "";
public ActionResult Disconnect()
{
OAuthConsumerContext consumerContext = new OAuthConsumerContext
{
ConsumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString(),
SignatureMethod = SignatureMethod.HmacSha1,
ConsumerSecret = ConfigurationManager.AppSettings["consumerSecret"].ToString()
};
OAuthSession oSession = new OAuthSession(consumerContext, Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlRequestToken,
Constants.OauthEndPoints.AuthorizeUrl,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlAccessToken);
oSession.ConsumerContext.UseHeaderForOAuthParameters = true;
if ((Session["AccessToken"] + "").Length > 0)
{
Session["FriendlyName"] = null;
oSession.AccessToken = new TokenBase
{
Token = Session["AccessToken"].ToString(),
ConsumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString(),
TokenSecret = Session["AccessTokenSecret"].ToString()
};
IConsumerRequest conReq = oSession.Request();
conReq = conReq.Get();
conReq = conReq.ForUrl(Constants.IaEndPoints.DisconnectUrl);
try
{
conReq = conReq.SignWithToken();
}
catch (Exception ex)
{
throw ex;
}
//Used just see the what header contains
string header = conReq.Context.GenerateOAuthParametersForHeader();
//This method will clean up the OAuth Token
txtServiceResponse = conReq.ReadBody();
//Reset All the Session Variables
Session.Remove("oauthToken");
// Dont remove the access token since this is required for Reconnect btn in the Blue dot menu
// Session.Remove("accessToken");
// Add the invalid access token into session for the display of the Disconnect btn
Session["InvalidAccessToken"] = Session["AccessToken"];
// Dont Remove flag since we need to display the blue dot menu for Reconnect btn in the Blue dot menu
// Session.Remove("Flag");
ViewBag.DisconnectFlg = "User is Disconnected from QuickBooks!";
//Remove the Oauth access token from the OauthAccessTokenStorage.xml
OauthAccessTokenStorageHelper.RemoveInvalidOauthAccessToken(Session["FriendlyEmail"].ToString());
}
return RedirectToAction("Index", "QuickBooks");
}
public ActionResult CleanUpOnDisconnect()
{
//perform the clean up here
// Redirect to Home when user clicks on ConenctToIntuit widget.
object value = Session["RedirectToDefault"];
if (value != null)
{
bool isTrue = (bool)value;
if (isTrue)
{
Session.Remove("InvalidAccessToken");
Session.Remove("RedirectToDefault");
return Redirect("/QuickBooks/index");
}
}
return RedirectToAction("Index", "QuickBooks");
}
private String consumerSecret, consumerKey, oauthLink, RequestToken, TokenSecret, oauth_callback_url;
public RedirectResult OAuthGrant()
{
oauth_callback_url = Request.Url.GetLeftPart(UriPartial.Authority) + ConfigurationManager.AppSettings["oauth_callback_url"];
consumerKey = ConfigurationManager.AppSettings["consumerKey"];
consumerSecret = ConfigurationManager.AppSettings["consumerSecret"];
oauthLink = Constants.OauthEndPoints.IdFedOAuthBaseUrl;
IToken token = (IToken)Session["requestToken"];
IOAuthSession session = CreateSession();
IToken requestToken = session.GetRequestToken();
Session["requestToken"] = requestToken;
RequestToken = requestToken.Token;
TokenSecret = requestToken.TokenSecret;
oauthLink = Constants.OauthEndPoints.AuthorizeUrl + "?oauth_token=" + RequestToken + "&oauth_callback=" + UriUtility.UrlEncode(oauth_callback_url);
return Redirect(oauthLink);
}
/// <summary>
/// Gets the Access Token
/// </summary>
/// <returns>Returns OAuth Session</returns>
protected IOAuthSession CreateSession()
{
OAuthConsumerContext consumerContext = new OAuthConsumerContext
{
ConsumerKey = consumerKey,
ConsumerSecret = consumerSecret,
SignatureMethod = SignatureMethod.HmacSha1
};
return new OAuthSession(consumerContext,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlRequestToken,
oauthLink,
Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlAccessToken);
}
}
..这里是 QuickBooks/Index
的 cshtml 页面@using System.Configuration
@using PubManager.Domain.WebSession
@{
string MenuProxy = Request.Url.GetLeftPart(UriPartial.Authority) + "/" + System.Configuration.ConfigurationManager.AppSettings["menuProxy"];
string OauthGrant = Request.Url.GetLeftPart(UriPartial.Authority) + "/" + System.Configuration.ConfigurationManager.AppSettings["grantUrl"];
ViewBag.Title = "MagManager - Intuit Anywhere";
string FriendlyName = (string)HttpContext.Current.Session["FriendlyName"] + "";
string FriendlyEmail = (string)HttpContext.Current.Session["FriendlyEmail"];
string FriendlyIdentifier = (string)HttpContext.Current.Session["FriendlyIdentifier"];
string realm = (string)Session["Realm"];
string dataSource = (string)Session["DataSource"];
string accessToken = (string)Session["AccessToken"] + "";
string accessTokenSecret = (string)Session["AccessTokenSecret"];
string invalidAccessToken = (string)Session["InvalidAccessToken"];
}
<h1>Intuit - QuickBooks Online</h1>
<div class="well">
@if (FriendlyName.Length == 0)
{
<script>
window.location.href = "/QuickBooks/OpenIdIndex";
</script>
}
else
{
<div id="IntuitInfo">
<strong>Open Id Information:</strong><br />
Welcome: @FriendlyName<br />
E-mail Address: @FriendlyEmail<br />
<br />
@if (accessToken.Length > 0 && invalidAccessToken == null)
{
<div id="oAuthinfo">
<a onclick="reconcileInvoices()" id="RecInvoices" class="btn btn-primary">Set Invoices Paid</a><br />
<br/>
<a onclick="recTax()" id="RecTax" class="btn btn-primary">Sync Tax Rates</a><br />
<br/>
@if (SessionContext.UseAccountCodes)
{
<a onclick="recProducts()" id="RecProducts" class="btn btn-primary">Sync Products</a><br />
<br />
}
<a href="/QuickBooks/ReconcileCustomers" id="Customers" class="btn btn-primary">Reconcile Customers</a><br/>
<br/>
<a href="/QuickBooks/Disconnect" id="Disconnect" class="btn btn-primary">
Disconnect from
QuickBooks
</a>
<br/><br/>
@*<a href="/QuickBooks/Customers" id="QBCustomers" class="btn btn-primary">Get QuickBooks Customer List</a><br/>
<br/>*@
@*<br />
<a href="/QuickBooks/Invoices" id="QBInvoices" class="btn btn-primary">Get QuickBooks Invoice List</a><br />
<br />*@
<br />
</div>
}
else
{
<br />
<ipp:connecttointuit></ipp:connecttointuit>
}
</div>
}
</div>
<script type="text/javascript" src="https://js.appcenter.intuit.com/Content/IA/intuit.ipp.anywhere-1.3.5.js"></script>
<script type="text/javascript">
intuit.ipp.anywhere.setup({
menuProxy: '@MenuProxy',
grantUrl: '@OauthGrant'
});
</script>