这个问题与已经被问过的其他问题类似,但答案没有帮助,而且我认为这是一个关键部分。我在MailChimp OAuth2流程的第4步,这需要对授权网址(see here)进行带外发布。它不断返回错误:invalid_grant,我理解它可以指示许多不同的错误。这是我的代码(我使用的是Yii2)。
// Controller action (authorize)
public function actionMailchimpAuthorize()
{
$redirect_uri = Url::toRoute(['controller/mailchimp-token'], 'https');
$base_uri = 'https://login.mailchimp.com/oauth2/authorize';
$params = '?response_type=code&client_id=' . Model::CLIENT_ID . '&redirect_uri=' . urlencode($redirect_uri);
$authorize_uri = $base_uri . $params;
return $this->render('mailchimpAuthorize', [
'authorize_uri' => $authorize_uri,
]);
}
// Controller action (token)
public function actionMailchimpToken($code=NULL)
{
$redirect_uri = Url::toRoute(['controller/mailchimp-token'], 'https');
$token_uri = 'https://login.mailchimp.com/oauth2/token';
$params = [
'grant_type' => 'authorization_code',
'client_id' => Model::CLIENT_ID,
'client_secret' => Model::CLIENT_SECRET,
'redirect_uri' => urlencode($redirect_uri),
'code' => $code,
];
$user_agent = 'oauth2-draft-v10';
$headers = ['Accept: application/json'];
$res = Utility::post($token_uri, $params, $user_agent, $headers);
var_dump($res);
}
// Utility
public function post($url, $params, $user_agent = NULL, $headers = NULL)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$post = http_build_query($params);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
isset($user_agent) ? curl_setopt($ch, CURLOPT_USERAGENT, $user_agent) : NULL;
isset($headers) ? curl_setopt($ch, CURLOPT_HTTPHEADER, $headers) : NULL;
$res = curl_exec($ch);
curl_close($ch);
return $res;
}
关于SO的答案在重定向URI匹配方面做了大量工作。但是有三个地方可以进入返回uri:在Mailchimp中注册应用程序时,在授权URL中,以及令牌URL。这三个都需要完全匹配,还是只需要auth和token URI?我尝试了各种组合无济于事。我的问题可能有所不同,但这是我唯一不清楚的事情(我认为)。和我之前的许多人一样,我对这个人发疯了。
答案 0 :(得分:0)
此解决方案由另一位开发人员提供给我。
commmon /组件/ Mailchimp.php:
namespace common\components;
class Mailchimp extends \yii\authclient\OAuth2
{
public $clientId = 'client id';
public $clientSecret = 'client secret';
public $authUrl = 'https://login.mailchimp.com/oauth2/authorize';
public $tokenUrl = 'https://login.mailchimp.com/oauth2/token';
// min function needed to extend – just put the return to true as I don’t care the return value
public function initUserAttributes()
{
return true;
}
}
控制器:
public function actionMailchimpAuthorize()
{
$oauthClient = new \common\components\Mailchimp();
$oauthClient->setReturnUrl(Url::toRoute(['controller/mailchimp-complete'], 'https));
$url = $oauthClient->buildAuthUrl();
$response = Yii::$app->getResponse()->redirect($url);
return $this->render('mailchimpAuthorize');
}
public function actionMailchimpComplete()
{
$code = Yii::$app->getRequest()->get('code');
$oauthClient = new \common\components\Mailchimp();
$oauthClient->setReturnUrl(Url::toRoute(['controller/mailchimp-complete'], 'https));
$accessToken = $oauthClient->fetchAccessToken($code);
// Complete MC flow with request to metadata url
$headers = [
'User-Agent:oauth2-draft-v10',
'Host:login.mailchimp.com',
'Accept:application/json',
'Authorization:OAuth ' . $oauthClient->getAccessToken()->token
];
$url = 'https://login.mailchimp.com/oauth2/metadata';
$res = Utility::get($url, $headers);
$dc = json_decode($res)->dc; // retrieve datacenter
return $this->render('mailchimpComplete', ['accessToken' => $accessToken, 'data' => $oauthClient]);
}
// save token-datacenter to database for making api calls
查看文件mailchimpComplete.php:
echo($data->getAccessToken()->token);
Mailchimp中app注册时设置的返回URI与上面列出的相同:https://myhost.com/controller/mailchimp-complete