doniys_a
@doniys_a
Backend-разработчик (Php, node.js, python, ruby)

Почему получаю ошибку при получении токена Mail.ru?

В общем суть вопроса в следующем:
Пытаюсь сделать авторизацию через апи mail.ru на сайте.

Вот собственно класс самого коннектора:
class Mail extends CApplicationComponent {

    public $app_id;
    public $public_key;
    public $secret_key;
    public $private_key;

    public $link         = "https://connect.mail.ru/oauth/";
    public $redirectUri  = "http://gethom.com/deploy/mlauth";
    public $responseType = "code";

    const TYPE_TOKEN      = 'token';
    const TYPE_CODE_TOKEN = 'code';

    public function init() {

    }

    public function authenticate() {

    }

    public function getAccessToken($code) {
        $link   = $this->link . "token";
        $params = array(
            'client_id'  => $this->app_id,
            'grant_type' => 'authorization_code',
            'code' => $code,
            'redirectUri' => $this->redirectUri,
            'client_secret' => $this->private_key,
        );

        $response = $this->getExecuteInfo($link, $params);
    }

    public function getExecuteInfo($url, $codeTask) {
        $curl = curl_init($url);

        echo "<br/><br/> {$url} <br/>";

        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $codeTask);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
        $response = curl_exec($curl);
        $curlInfo = curl_getinfo($curl);

        echo "<pre>";
        var_dump($curlInfo);
        var_dump($codeTask);
        curl_close($curl);

        var_dump($response);
        exit;

        return CJSON::decode($response);

    }

    public function loginUrl() {
        $params = array(
            'client_id'     => $this->app_id,
            'response_type' => $this->responseType,
            'redirect_uri'  => $this->redirectUri,
        );
        return ("<a href='" . $this->link . "authorize" . "?" . urldecode(http_build_query($params)) . '\'>Mail.ru</a>');
    }

}


Вывод метод контроллера, который отвечает за авторизацию (для тестирования):
public function actionMail() {
        echo Yii::app()->mr->loginUrl();

        if (isset($_GET['code'])) {
            echo 123;
            Yii::app()->mr->getAccessToken($_GET['code']);
        }
    }


И вот на этапе получения токена получаю ошибку:
{"error":"invalid_request"}

вот вывод curl_info:
array(26) {
  ["url"]=>
  string(35) "https://connect.mail.ru/oauth/token"
  ["content_type"]=>
  string(30) "text/javascript; charset=utf-8"
  ["http_code"]=>
  int(400)
  ["header_size"]=>
  int(221)
  ["request_size"]=>
  int(195)
  ["filetime"]=>
  int(-1)
  ["ssl_verify_result"]=>
  int(0)
  ["redirect_count"]=>
  int(0)
  ["total_time"]=>
  float(0.055586)
  ["namelookup_time"]=>
  float(0.00258)
  ["connect_time"]=>
  float(0.010342)
  ["pretransfer_time"]=>
  float(0.035546)
  ["size_upload"]=>
  float(657)
  ["size_download"]=>
  float(27)
  ["speed_download"]=>
  float(485)
  ["speed_upload"]=>
  float(11819)
  ["download_content_length"]=>
  float(27)
  ["upload_content_length"]=>
  float(657)
  ["starttransfer_time"]=>
  float(0.038127)
  ["redirect_time"]=>
  float(0)
  ["certinfo"]=>
  array(0) {
  }
  ["primary_ip"]=>
  string(14) "94.100.185.159"
  ["primary_port"]=>
  int(443)
  ["local_ip"]=>
  string(12) "ХХ.ХХ.ХХХ.ХХХ"
  ["local_port"]=>
  int(57702)
  ["redirect_url"]=>
  string(0) ""
}

Параметры, которые передает curl:
array(5) {
  ["client_id"]=>
  string(6) "111111"
  ["grant_type"]=>
  string(18) "authorization_code"
  ["code"]=>
  string(32) "39b8c2f0fa5e0710752d2447d51abf4c"
  ["redirectUri"]=>
  string(31) "link_redirect"
  ["client_secret"]=>
  string(32) "secret_key"
}

Естественно секретный ключ, редирект ури и appId я заменил на произвольные.
Подскажите, что я делаю не так?
  • Вопрос задан
  • 4009 просмотров
Пригласить эксперта
Ответы на вопрос 1
doniys_a
@doniys_a Автор вопроса
Backend-разработчик (Php, node.js, python, ruby)
тема закрыта, вот конечный класс для авторизации на mail.ru

<?php

class Mail extends CApplicationComponent {

    public $app_id;
    public $public_key;
    public $secret_key;
    public $private_key;

    public $link         = "https://connect.mail.ru/oauth/";
    public $redirectUri  = "http://gethom.com/deploy/mlauth";
    public $responseType = "code";

    public $access_token = null;
    public $refresh_token = null;

    const TYPE_TOKEN      = 'token';
    const TYPE_CODE_TOKEN = 'code';

    public function init() {

    }

    public function authenticate() {

    }

    public function getAccessToken($code) {
        $link   = $this->link . "token";
        $params = array(
            'client_id'  => $this->app_id,
            'client_secret' => $this->private_key,
            'grant_type' => 'authorization_code',
            'code' => $code,
            'redirect_uri' => $this->redirectUri,
        );

        $response = $this->makeRequest($link, $params);

        if (isset($response['access_token'])) {
            $this->access_token  = $response['access_token'];
            $this->refresh_token = $response['refresh_token'];
        }
    }

    public function makeRequest($link, $params, $jsonFormat = false) {
        $ch = $this->initRequest($link,  array('data' => $params));

        $result = curl_exec($ch);
        $headers = curl_getinfo($ch);

        if (curl_errno($ch) > 0) {
            throw new Exception(curl_error($ch), curl_errno($ch));
        }

        if ($headers['http_code'] != 200) {
            Yii::log(
                'Invalid response http code: ' . $headers['http_code'] . '.' . PHP_EOL .
                'URL: ' . $link . PHP_EOL .
                'Options: ' . var_export($params, true) . PHP_EOL .
                'Result: ' . $result,
                CLogger::LEVEL_ERROR, 'application.extensions.eauth'
            );
            throw new Exception(Yii::t('eauth', 'Invalid response http code: {code}.', array('{code}' => $headers['http_code'])), $headers['http_code']);
        }

        curl_close($ch);

        return ($jsonFormat) ? $result : CJSON::decode($result);

    }

    public function loginUrl() {
        $params = array(
            'client_id'     => $this->app_id,
            'response_type' => $this->responseType,
            'redirect_uri'  => $this->redirectUri,
        );
        return ("<a href='" . $this->link . "authorize" . "?" . urldecode(http_build_query($params)) . '\'>Mail.ru</a>');
    }

    public function initRequest($url, $options) {
        $ch = curl_init();
        //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // error with open_basedir or safe mode
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);

        if (isset($options['referer'])) {
            curl_setopt($ch, CURLOPT_REFERER, $options['referer']);
        }

        if (isset($options['headers'])) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $options['headers']);
        }

        if (isset($options['query'])) {
            $url_parts = parse_url($url);
            if (isset($url_parts['query'])) {
                $query = $url_parts['query'];
                if (strlen($query) > 0) {
                    $query .= '&';
                }
                $query .= http_build_query($options['query']);
                $url = str_replace($url_parts['query'], $query, $url);
            }
            else {
                $url_parts['query'] = $options['query'];
                $new_query = http_build_query($url_parts['query']);
                $url .= '?' . $new_query;
            }
        }

        if (isset($options['data'])) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $options['data']);
        }

        curl_setopt($ch, CURLOPT_URL, $url);
        return $ch;
    }

}

Код котроллера:
public function actionMail() {
        echo Yii::app()->mr->loginUrl();

        if (isset($_GET['code'])) {
            Yii::app()->mr->getAccessToken($_GET['code']);
            if (Yii::app()->mr->access_token) {
                echo 'login on mail ru, welcome!';
            }
        }
    }
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы