POST с использованием CURL в PHP дает неверный запрос Ошибка

Я использую ниже метод post для учетной записи google, используя curl, но он дает мне ошибку invalid_request.

POST /o/oauth2/token HTTP/1.1 Host: accounts.google.com Content-Type: application/x-www-form-urlencoded code=4/ux5gNj-_mIu4DOD_gNZdjX9EtOFf& client_id=1084945748469-eg34imk572gdhu83gj5p0an9fut6urp5.apps.googleusercontent.com& client_secret=CENSORED& redirect_uri=http://localhost/oauth2callback& grant_type=authorization_code 

Вот мой PHP-код с завитой

 $text ='test'; $URL = "https://accounts.google.com/o/oauth2/token"; $header = array( "POST /o/oauth2/token HTTP/1.1", "Host: accounts.google.com", "Content-type: application/atom+xml;charset=\"utf-8\"", "Accept: text/xml", "Cache-Control: no-cache", "code=[my_code]&client_id=[my_client_id]&client_secret=[my_client_secret]& redirect_uri=http://localhost/curl_resp.php&grant_type=authorization_code", "Content-length: ".strlen($text), ); $xml_do = curl_init(); curl_setopt($xml_do, CURLOPT_URL, $URL); curl_setopt($xml_do, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($xml_do, CURLOPT_TIMEOUT, 10); curl_setopt($xml_do, CURLOPT_RETURNTRANSFER, true); curl_setopt($xml_do, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($xml_do, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($xml_do, CURLOPT_POST, false); curl_setopt($xml_do, CURLOPT_POSTFIELDS, $text); curl_setopt($xml_do, CURLOPT_HTTPHEADER, $header); 

И у меня есть неверная ошибка запроса

Я ничего не знаю об использовании API oAuth Google, но из тех примеров, которые я рассматривал до сих пор, похоже, что вы должны передавать значения (например, code , client_id и т. Д.) В полях сообщений, а не напрямую в заголовке HTTP.

Следующий пример все еще не работает полностью, но вместо получения ошибки invalid_request он дает вам invalid_grant . Я думаю, что в дополнение к тому, что я упомянул (возможно, вам нужны новые учетные данные из Google или что-то еще), но это может сделать вас на один шаг ближе, по крайней мере:

 $post = array( "grant_type" => "authorization_code", "code" => "your_code", "client_id" => "your_client_id", "client_secret" => "your_client_secret", "redirect_uri" => "http://localhost/curl_resp.php" ); $postText = http_build_query($post); $url = "https://accounts.google.com/o/oauth2/token"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postText); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $result = curl_exec($ch); var_dump($result); // gets an error, "invalid_grant" 

Ответ на ваш запрос на самом деле включает очень читаемое описание проблемы:

Для запросов POST требуется заголовок Content-length .

Почему у вас установлено значение CURLOPT_POST равным false ?

  curl_setopt($xml_do, CURLOPT_POST, false); 

Хотя некоторые конфигурации cURL автоматически изменят это на true, если установлено CURLOPT_POSTFIELDS, у вас нет действительного почтового поля.

Полные данные для отправки в HTTP-режиме «POST». Чтобы опубликовать файл, добавьте имя файла с помощью @ и используйте полный путь. Тип файла может быть явно указан, следуя имени файла с типом в формате '; type = mimetype'. Этот параметр может быть передан как строка с urlencoded, например 'para1 = val1 & para2 = val2 & …', или как массив с именем поля в качестве ключа и данными поля в качестве значения. Если значением является массив, заголовок Content-Type будет установлен в multipart / form-data. Начиная с PHP 5.2.0, значение должно быть массивом, если файлы передаются этому параметру с префиксом @.

Он должен быть либо в синтаксисе param = value, либо в массиве.

Я использовал массив сообщений в методе CURL и действительный код Google, и он работал для меня

У меня также была такая же проблема, когда google возвращает «invalid_xxx».

После долгих исследований и устранения неполадок проблема заключается в кодировании самой формы! Не используйте функцию «http_builder_query», поскольку она загружает строку, и Google не может ее распознать. Пример :

http_builder_query Выход: "code = 4% 252FYYUT71KJ6 …"

в сравнении с

просто нормальная строка: "code = 4 / YYUT71KJ6 …"

Вот мой рабочий код, в котором я разместил «x» в местах, где нужны ваши собственные данные (взятые и измененные из проверки подлинности Google ).

  $code_from_user_login = "4/YYUT71KJ6...."; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://accounts.google.com/o/oauth2/token"); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); $post_params = "code=" . $code_from_user_login . "&"; $post_params .= "redirect_uri=http://www.x.com/&"; $post_params .= "client_id=x.apps.googleusercontent.com&"; $post_params .= "client_secret=x&"; $post_params .= "grant_type=authorization_code&"; curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params); $result = curl_exec($ch); print($result); 

Результат будет таким:

  '{ "access_token" : "ya29.AHES6ZSwJSHpTZ1t....", "token_type" : "Bearer", "expires_in" : 3599, "id_token" : "eyJhbGciOiJSUzI1NiIsImtpZCI6IjU0MDQxOTZlMmQzOGNjYTA2MW...." }' 

Когда у вас есть «access_token», получите доступ к данным профиля с помощью этого URL-адреса: https://www.googleapis.com/oauth2/v1/userinfo?access_token=YOUR_ACCESS_TOKEN_HERE

~ end ~