I'm working OAuth connect Yahoo.jp login API
I try sending http request use file_get_contents but It's return errors
Here is my code
// my apps setting
$client_id = 'dj0zaiZpP~~~~~~~~~~~~~~~';
$appSecret = '129ad~~~~~~~~~~~~~~~~';
// the data to send
$data = array(
'grant_type' => 'authorization_code',
'redirect_uri' => 'My_redierct_page',
'code' => $_GET['code']
);
$data = http_build_query($data);
$header = array(
"Authorization: Basic " . base64_encode($client_id . ':' . $appSecret),
"Content-Type: application/x-www-form-urlencoded",
"Content-Length: ".strlen($data)
);
// build your http request
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => implode("\r\n", $header),
'content' => $data,
'timeout' => 10
)
));
// send it
$resp = file_get_contents('https://auth.login.yahoo.co.jp/yconnect/v1/token', false, $context);
$json = json_decode($resp);
echo($json->token_type . " " . $json->access_token);
The result...
file_get_contents(https://auth.login.yahoo.co.jp/yconnect/v1/token): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request in /var/www/html/api/auth_proc2.php on line 33
Here is another error message get using set_error_handler()
file_get_contents(): Content-type not specified assuming application/x-www-form-urlencoded
I can't understand this situation
Because I send Content-type in http header
and allow_url_fopen = on in my php.ini
Please help me~! Thanks.
The other thing I'd suggest using is CURL rather then file_get_contents for multiple reasons; first you'll have a lot more control over the request, second its more standard to use curl requests when dealing with API's, and third you'll be able to see better what your problem is.
Try replacing your code with the following and see what you get.
$client_id = 'dj0zaiZpP~~~~~~~~~~~~~~~';
$appSecret = '129ad~~~~~~~~~~~~~~~~';
$data = array(
'grant_type' => 'authorization_code',
'redirect_uri' => 'My_redierct_page',
'code' => $_GET['code']
);
$curl = curl_init('https://auth.login.yahoo.co.jp/yconnect/v1/token');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl, CURLOPT_USERPWD, $client_id . ':' . $appSecret);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
$info = curl_getinfo($curl);
print_r($response);
echo '<br /><br />';
print_r($info);
curl_close($curl);
I assume its probably because your using Content-Type and not Content-type and Content-Length instead of Content-length.
Related
I am trying to connect to Moz API V2, using HTTP Request by file get contents function but I am new using this... could you guys help me?
Example HTPP Request in their doc:
POST /v2/url_metrics
Host: lsapi.seomoz.com
Content-Length: [length of request payload in bytes]
User-Agent: [user agent string]
Authorization: Basic [credentials]
{
"targets": ["facebook.com"]
}
Here's the code I am trying:
$url = 'https://lsapi.seomoz.com/v2/url_metrics';
$domains = json_encode(['targets' => 'moz.com']);
$opts = ['http' =>
[
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded\r\n'.
("Authorization: Basic " . base64_encode("mozscape-XXXXX:XXXXX")),
'content-length' => strlen($domains),
'user-agent' => $_SERVER['HTTP_USER_AGENT'],
'content' => $domains,
]
];
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
print_r($result);
Here is the link of documentation : https://moz.com/help/links-api/making-calls/url-metrics
I got nothing when I print result, Probably I am missing some parameter... :(
Thank you for your time :)
Most probably you're simply making an invalid request. You declare the content type as application/x-www-form-urlencoded yet sending the data as application/json.
You also need basic error handling (eg. in case of invalid credentials).
I'd write it this way:
$url = 'https://lsapi.seomoz.com/v2/url_metrics';
$content = json_encode(['targets' => 'moz.com']);
$opts = ['http' => [
'method' => 'POST',
'content' => $content,
'header' => implode("\r\n", [
'Authorization: Basic ' . base64_encode("mozscape-XXXXX:XXXXX"),
'Content-Type: application/json',
'Content-Length: ' . strlen($content),
'User-Agent: ' . $_SERVER['HTTP_USER_AGENT'],
]),
]];
$stream = fopen($url, 'r', false, stream_context_create($opts));
if (!is_resource($stream)) {
die('The call failed');
}
// header information as well as meta data
// about the stream
var_dump(stream_get_meta_data($stream));
// actual data
var_dump(stream_get_contents($stream));
// free resources
fclose($stream);
To be honest, the sockets & fopen is pretty low level. It would be better for you to use an abstraction layer instead: like Guzzle.
Sorry for late solution I forgot to post here before...
Maybe someone is looking for how to use moz API V2 with PHP...
$username='Access ID';
$password='Secret Key';
$URL='https://lsapi.seomoz.com/v2/url_metrics';
$payload = json_encode(array("targets" => ["moz.com"]));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$URL);
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout after 30 seconds
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
$result=curl_exec ($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); //get status code
curl_close ($ch);
print_r(json_decode($result, true));
I have this json data:
{
userID: 'a7664093-502e-4d2b-bf30-25a2b26d6021',
itemKind: 0,
value: 1,
description: 'Saude',
itemID: '03e76d0a-8bab-11e0-8250-000c29b481aa'
}
and I need to post into json url:
http://domain/OnLeagueRest/resources/onleague/Account/CreditAccount
using php how can I send this post request?
You can use CURL for this purpose see the example code:
$url = "your url";
$content = json_encode("your data to be sent");
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER,
array("Content-type: application/json"));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ( $status != 201 ) {
die("Error: call to URL $url failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
}
curl_close($curl);
$response = json_decode($json_response, true);
Without using any external dependency or library:
$options = array(
'http' => array(
'method' => 'POST',
'content' => json_encode( $data ),
'header'=> "Content-Type: application/json\r\n" .
"Accept: application/json\r\n"
)
);
$context = stream_context_create( $options );
$result = file_get_contents( $url, false, $context );
$response = json_decode( $result );
$response is an object. Properties can be accessed as usual, e.g. $response->...
where $data is the array contaning your data:
$data = array(
'userID' => 'a7664093-502e-4d2b-bf30-25a2b26d6021',
'itemKind' => 0,
'value' => 1,
'description' => 'Boa saudaÁ„o.',
'itemID' => '03e76d0a-8bab-11e0-8250-000c29b481aa'
);
Warning: this won't work if the allow_url_fopen setting is set to Off in the php.ini.
If you're developing for WordPress, consider using the provided APIs: https://developer.wordpress.org/plugins/http-api/
Beware that file_get_contents solution doesn't close the connection as it should when a server returns Connection: close in the HTTP header.
CURL solution, on the other hand, terminates the connection so the PHP script is not blocked by waiting for a response.
use CURL luke :) seriously, thats one of the best ways to do it AND you get the response.
I want to get an access token to call to Google Directory API. I have seen several posts with PHP Curl code, but everytime there has to be a human action to permit access before you get the access token. Is there a way to make a CURL request and get the access token directly?
This is my code so far:
define("CALLBACK_URL", "http://localhost/los/index");
define("AUTH_URL", "https://accounts.google.com/o/oauth2/auth");
define("ACCESS_TOKEN_URL", "https://oauth2.googleapis.com/token");
define("CLIENT_ID", "**.apps.googleusercontent.com");
define("CLIENT_SECRET", "**");
define("SCOPE", "https://www.googleapis.com/auth/admin.directory.device.chromeos");
function getToken(){
$curl = curl_init();
$params = array(
CURLOPT_URL =>
ACCESS_TOKEN_URL."?"."&grant_type=authorization_code"."&client_id=".
CLIENT_ID."&client_secret=". CLIENT_SECRET."&redirect_uri=". CALLBACK_URL,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_ENCODING => '',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_NOBODY => false,
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"Content-Length: 0",
"content-type: application/x-www-form-urlencoded",
"accept: *",
"accept-encoding: gzip, deflate",
),
);
curl_setopt_array($curl, $params);
$response = curl_exec($curl);
$err = curl_error($curl);
echo $response;
curl_close($curl);
if ($err) {
echo "cURL Error #01: " . $err;
} else {
$response = json_decode($response, true);
if(array_key_exists("access_token", $response)) return $response;
if(array_key_exists("error", $response)) echo $response["error_description"];
echo "cURL Error #02: Something went wrong! Please contact admin.";
}
}
When I run it I get this error message:
{ "error": "invalid_request", "error_description": "Missing required parameter: code" }Missing required parameter: codec
I've just been through a similar problem with using PHP cURL to get an access token from the http code returned by the Google API after the user authorizes the consent screen. Here's my long-winded answer:
From least to most important: you should start by fixing the brackets after your if conditions:
if (array_key_exists("access_token", $response)) {
return $response
} elseif (array_key_exists("error", $response)) {
echo $response["error_description"];
echo "cURL Error #02: Something went wrong! Please contact admin.";
}
The error message "Missing required parameter: code" appears because you need to post the code that was returned in the url after the client authorizes your app. You'd do that by doing something like:
CURLOPT_URL => ACCESS_TOKEN_URL."?"."&code=".$_GET['code']."&grant_type=authorization_code"."&client_id=".CLIENT_ID."&client_secret=". CLIENT_SECRET."&redirect_uri=".CALLBACK_URL,
To make it more semantic you'd define the $authorization code variable before that:
$authorizationCode = $_GET['code'];
Lastly, the most important part is that to get an Access Token from Google you need to used the cURL post method as shown in the documentation:
https://developers.google.com/identity/protocols/oauth2/web-server#exchange-authorization-code
You can do that with PHP cURL with this command:
curl_setopt( $ch, CURLOPT_POST, 1);
But then you need to break your URL into two parts: the host and the fields to be posted. To make it easier to read, you can setup your endpoint and the fields into variables:
$endpoint = 'https://oauth2.googleapis.com/token';
$fieldsToPost = array(
// params for the endpoint
'code' => $authorizationCode, //being that $authorizationCode = $_GET['code'];
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET,
'redirect_uri' => CALLBACK_URL,
'grant_type' => 'authorization_code',
);
Then you can use the $enpoint to set the url and http_build_query() to set up your fields. In the end, adapting your code to the code that worked for me would look something like this:
function getToken() {
$endpoint = 'https://oauth2.googleapis.com/token';
$fieldsToPost = array(
// params for the endpoint
'code' => $authorizationCode, //being that $authorizationCode = $_GET['code'];
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET,
'redirect_uri' => CALLBACK_URL,
'grant_type' => 'authorization_code',
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($fieldsToPost));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE );
// get curl response, json decode it, and close curl
$googleResponse = curl_exec($curl);
$curl_error = curl_errno($curl);
$googleResponse = json_decode( $googleResponse, TRUE );
curl_close( $curl );
return array( // return response data
'url' => $endpoint . '?' . http_build_query( $params ),
'endpoint' => $endpoint,
'params' => $params,
'has_errors' => isset( $googleResponse['error'] ) ? TRUE : FALSE, // b oolean for if an error occured
'error_message' => isset( $googleResponse['error'] ) ? $googleResponse['error']['message'] : '', // error message
'curl_error' => $curl_error, //curl_errno result
'google_response' => $googleResponse // actual response from the call
);
}
To check the response you can use the following print function to see the response:
if (isset($_GET['code'])) {
$response = getToken();
echo '<pre>';
print_r($response);
die();
}
I know it's been a long time and you've probably found a workaround but I hope this is still useful for future projects. Cheers!
file_get_contents not working for fetching fata from facebook using batch requests.Am using the code below:
$url='https://graph.facebook.com/?batch=[{ "method": "POST", "relative_url":"method/fql.query?query=SELECT+first_name+from+user+where+uid=12345678"}]& access_token=xxxxxxx&method=post';
echo $post = file_get_contents($url,true);
it produces
Warning: file_get_contents(graph.facebook.com/?batch=[{ "method": "POST", "relative_url": "method/fql.query?query=SELECT+first_name+from+user+where+uid=12345"}]&access_to ken=xxxx&method=post): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /home/user/workspace/fslo/test.php on line 9
I would say the most likely answer to this is that you need to pass the URL values through urlencode() - particularly the JSON string.
Also, you should be POSTing the data.
Try this code:
NB: I presume you are building the URL from several variables. If you edit the question with your actual code, I will provide a solution using that code
<?php
$baseURL = 'https://graph.facebook.com/';
$requestFields = array (
'batch' => '[{"method":"POST","relative_url":"method/fql.query?query=SELECT+first_name+from+user+where+uid=12345678"}]',
'access_token' => 'whatever'
);
$requestBody = http_build_query($requestFields);
$opts = array(
'http'=>array(
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n"
. "Content-Length: ".strlen($requestBody)."\r\n"
. "Connection: close\r\n",
'content' => $requestBody
)
);
$context = stream_context_create($opts);
$result = file_get_contents($baseURL, FALSE, $context);
A "more standard" way to do this these days is with cURL:
<?php
$baseURL = 'https://graph.facebook.com/';
$requestFields = array (
'batch' => '[{"method":"POST","relative_url":"method/fql.query?query=SELECT+first_name+from+user+where+uid=12345678"}]',
'access_token' => 'whatever'
);
$requestBody = http_build_query($requestFields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $baseURL);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: '.strlen($requestBody),
'Connection: close'
));
$post = curl_exec($ch);
I have this json data:
{
userID: 'a7664093-502e-4d2b-bf30-25a2b26d6021',
itemKind: 0,
value: 1,
description: 'Saude',
itemID: '03e76d0a-8bab-11e0-8250-000c29b481aa'
}
and I need to post into json url:
http://domain/OnLeagueRest/resources/onleague/Account/CreditAccount
using php how can I send this post request?
You can use CURL for this purpose see the example code:
$url = "your url";
$content = json_encode("your data to be sent");
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER,
array("Content-type: application/json"));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ( $status != 201 ) {
die("Error: call to URL $url failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
}
curl_close($curl);
$response = json_decode($json_response, true);
Without using any external dependency or library:
$options = array(
'http' => array(
'method' => 'POST',
'content' => json_encode( $data ),
'header'=> "Content-Type: application/json\r\n" .
"Accept: application/json\r\n"
)
);
$context = stream_context_create( $options );
$result = file_get_contents( $url, false, $context );
$response = json_decode( $result );
$response is an object. Properties can be accessed as usual, e.g. $response->...
where $data is the array contaning your data:
$data = array(
'userID' => 'a7664093-502e-4d2b-bf30-25a2b26d6021',
'itemKind' => 0,
'value' => 1,
'description' => 'Boa saudaÁ„o.',
'itemID' => '03e76d0a-8bab-11e0-8250-000c29b481aa'
);
Warning: this won't work if the allow_url_fopen setting is set to Off in the php.ini.
If you're developing for WordPress, consider using the provided APIs: https://developer.wordpress.org/plugins/http-api/
Beware that file_get_contents solution doesn't close the connection as it should when a server returns Connection: close in the HTTP header.
CURL solution, on the other hand, terminates the connection so the PHP script is not blocked by waiting for a response.
use CURL luke :) seriously, thats one of the best ways to do it AND you get the response.