MailChimp OAuth2 访问令牌

MailChimp OAuth2 Access Token

这个问题与已经提出的其他问题类似,但答案没有帮助,我认为缺少一个关键部分。我在 MailChimp OAuth2 流程的第 4 步,这需要带外 post 来授权 url (see here)。它保持 returning 错误: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 匹配有很大影响。但是可以在三个地方输入 return uri:在注册应用程序时在 Mailchimp 中,在授权中 url,以及令牌中 url。这三个都需要精确计算,还是只需要验证和令牌 URI?我试过各种组合都无济于事。我的问题可能有所不同,但这是我唯一不清楚的(我认为)。和我之前的许多人一样,我对这个感到疯狂。

此解决方案是由另一位开发人员提供给我的。

commmon/components/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 中应用程序注册时设置的 return URI 与上面列出的相同:https://myhost.com/controller/mailchimp-complete