我正在开发一个新应用程序,该程序可与MailChimp集成。基本上,它使用户可以轻松地将其客户联系信息直接导出到MailChimp帐户(即,导出到MailChimp中的特定邮件列表)。所有这些都有效,并且与我的问题无关。
为了避免每次都不要求用户输入MailChimp凭证,我将实现如下所述的oauth2授权工作流程:http://apidocs.mailchimp.com/oauth2/
在步骤1-3中工作正常,但是步骤4杀死了我。这是我第一次使用oauth,但我似乎了解一些基本知识。
这是我的问题:
[当我对https://login.mailchimp.com/oauth2/token -URI进行POST调用时,要获取最终的访问令牌,我会不断在JSON结果中获取错误:“ invalid_grant”
我已经检查了请求和响应流,我的网址已正确编译。
这是我在控制器中的代码:
((GrantEcoAccess只是授予对另一个应用程序的访问权-其余的应该是不言自明的)
public class HomeController : ApplicationController
{
private readonly string authorize_uri = "https://login.mailchimp.com/oauth2/authorize";
private readonly string access_token_uri = "https://login.mailchimp.com/oauth2/token";
private readonly string mailchimp_clientid2 = "xxx";
private readonly string mailchimp_secret2 = "yyy";
...
public ActionResult GrantEcoAccess()
{
//if exist: use saved token
var user = (Mailchimp_users)Session["user"];
if (!string.IsNullOrWhiteSpace(user.EcoToken))
return RedirectToAction("GrantMailChimpAccess");
// if !
var url = "https://secure.e-conomic.com/secure/api1/requestaccess.aspx?role=superuser&appId=MailChimp&redirectUrl=http://localhost:18017/Home/IncomingToken";
Redirect(url).ExecuteResult(ControllerContext);
return null;
}
public ActionResult IncomingToken(string token)
{
var user = (Mailchimp_users)Session["user"];
user.EcoToken = token;
EcoSession.DataSession.Refresh(System.Data.Objects.RefreshMode.ClientWins, user);
EcoSession.DataSession.SaveChanges();
return RedirectToAction("GrantMailChimpAccess");
}
public ActionResult GrantMailChimpAccess()
{
//if exist: use saved token
var user = (Mailchimp_users)Session["user"];
if (!string.IsNullOrWhiteSpace(user.MailChimpToken))
return RedirectToAction("Index", "Subscribe");
//if !
var url = string.Format("{0}?response_type=code&client_id={1}&redirect_uri=", authorize_uri, mailchimp_clientid2, "http://127.0.0.1:18017/Home/IncomingMailChimpToken");
Redirect(url).ExecuteResult(ControllerContext);
return null;
}
public ActionResult IncomingMailChimpToken(string code)
{
var url = "https://login.mailchimp.com/oauth2/token?grant_type=authorization_code&client_id=XX&client_secret=XX&code=" + code + "&redirect_uri=http://127.0.0.1:18017/Home/AuthComplete";
//var url = string.Format("?grant_type=authorization_code&client_id={0}&client_secret={1}&code={2}&redirect_uri={3}", mailchimp_clientid, mailchimp_secret, code, Url.Action("AuthComplete"));
Response.Clear();
StringBuilder sb = new StringBuilder();
sb.Append("<html>");
sb.AppendFormat(@"<body onload='document.forms[""form""].submit()'>");
sb.AppendFormat("<form name='form' action='{0}' method='post'>", access_token_uri);
sb.Append("<input type='hidden' name='grant_type' value='authorization_code'>");
sb.AppendFormat("<input type='hidden' name='client_id' value='{0}'>", mailchimp_clientid2);
sb.AppendFormat("<input type='hidden' name='client_secret' value='{0}'>", mailchimp_secret2);
sb.AppendFormat("<input type='hidden' name='code' value='{0}'>", code);
sb.AppendFormat("<input type='hidden' name='redirect_uri' value='{0}'>", "http://127.0.0.1:18017/Home/AuthComplete");
// Other params go here
sb.Append("</form>");
sb.Append("</body>");
sb.Append("</html>");
Response.Write(sb.ToString());
Response.End();
return null;
}
public ActionResult AuthComplete(string access_token, string expires_in, string scope)
{
if (string.IsNullOrWhiteSpace(access_token))
throw new Exception("Could not authorize user with MailChimp");
var user = (Mailchimp_users)Session["user"];
user.MailChimpToken = access_token;
EcoSession.DataSession.Refresh(System.Data.Objects.RefreshMode.ClientWins, user);
EcoSession.DataSession.SaveChanges();
return RedirectToAction("Index", "Subscribe");
}
}
是步骤4杀死了我,而不是步骤5。
步骤4是“您的应用程序必须使用代码对access_token_uri进行带外请求”
这里的重点是“带外”。您必须构建并发送发布请求服务器端。客户端不应具有您的mailchimp_secret
您的IncomingMailChimpToken可能看起来像这样:
public ActionResult IncomingMailChimpToken(string code)
{
string mcPostData = String.Format(
"grant_type={0}&client_id={1}&client_secret={2}&code={3}&redirect_url={4}",
System.Web.HttpUtility.UrlEncode("authorization_code"),
System.Web.HttpUtility.UrlEncode(mailchimp_clientid2),
System.Web.HttpUtility.UrlEncode(mailchimp_secret2),
System.Web.HttpUtility.UrlEncode(code),
System.Web.HttpUtility.UrlEncode("http://127.0.0.1:18017/Home/AuthComplete")
);
WebRequest request = WebRequest.Create(access_token_uri);
// Set the Method property of the request to POST.
request.Method = "POST";
request.ContentType = "application/json";
byte[] byteArray = Encoding.UTF8.GetBytes(mcPostData);
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Cleanup the streams and the response.
reader.Close ();
dataStream.Close ();
response.Close ();
// parse the json responseFromServer to extract token, expires_in and scope
// and call AuthComplete with these params
}
您应该使用post在正文中发送您的请求参数,如果您使用的是curl php,则可以这样做:
$value = http_build_query($params); //params is an array
curl_setopt($ch, CURLOPT_POSTFIELDS, $value);
值应如下所示:
grant_type=authorization_code&client_id=635959587059&client_secret=0da3e7744949e1406b7b250051ee1a95&code=1edf2589e664fd317f6a7ff5f97b42f7&redirect_uri=http%3A%2F%2F192.168.1.8%2Foauth%2Fcomplete.php
[请注意,您应该以查询字符串的形式创建主体请求,不要发送json,它们不会找到您的参数。如果执行此操作后收到无效的授权响应或其他内容,请检查用于获取第一个代码的重定向uri是否与为获取令牌而发送的重定向uri完全相同。
此外,对于使用PHP的用户,要使其与mailchimp documentation状态相匹配,请使用此:
curl_setopt($ch, CURLOPT_USERAGENT, 'oauth2-draft-v10');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
如果您不想自己实现,则有一个不错的包装器,它处理对MailChimp的oAuth2和RESTapi调用。