The problem
I'm trying to get the e-mail of a user with the Google API.
I want to do it using cURL and PHP.
So basically:
=> You click on a button, you're redirected to https://accounts.google.com/o/oauth2/v2/auth + scope + access_type etc.
=> Once you choosed your account, you're redirected to the new page, and it's in this page that I have the problem.
What I tried
Searching on Stack Overflow and modifying my code but nothing worked. Also, I didn't find anything apart from: This
But there is no solution and it's not really the same problem
The error is
Array
(
[error] => invalid_request
[error_description] => You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure. You can let the app developer know that this app doesn't comply with one or more Google validation rules.
)
So I look at the "Google validation rules":
https://developers.google.com/identity/protocols/oauth2/web-server#uri-validation
And, I think that my code respects all theses rules.
Show some code
Note:
$google_id and $google_secret are defined earlier with the correct values.
$code = $_GET["code"];
if (!isset($code)) exit();
# The url oauth2 google API
$url = "https://oauth2.googleapis.com/token";
# The data you want to send via POST
$redirect_uri = urlencode("http://localhost:9000/loginWithGoogleProcess.php"); # redirect_uri
$fields = array(
'code' => $code,
'client_id' => $google_id,
'client_secret' => $google_secret,
'redirect_uri' => $redirect_uri,
'grant_type' => "authorization_code"
);
# Convert array to string URL
$fields_string = http_build_query($fields);
# Open connection
$ch = curl_init();
# Set basic options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
# Curl SSL
# If there is not these lines here, the response will be false
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
# So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
# Execute post
$result = json_decode(curl_exec($ch), true);
print_r($result);
And what results from print_r is :
Array
(
[error] => invalid_request
[error_description] => You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure. You can let the app developer know that this app doesn't comply with one or more Google validation rules.
)
Related
I need to allow users of my platform to link their Instagram account through the Instagram Basic Display API.
When I make the call to get the code to exchange for the Access Token, it is always the same and results in an error in the next step.
These are the steps I'm performing, following this official guide:
GET request with these parameters: https://api.instagram.com/oauth/authorize?client_id=XXXXX&redirect_uri=XXXXX&scope=user_profile&response_type=code
POST request to https://api.instagram.com/oauth/access_token via cURL in PHP passing the parameters as the second code snippet below
GET request with 'https://graph.instagram.com/' . $result->user_id . '?fields=username&access_token=' . $result->access_token via cURL in PHP
The process fail between 1 and 2, because step one always returns the same code even though I have made several attempts with different accounts
This is the HTML form for the code request. Successfully opens the Instagram login page:
<a class="insta-con" href="https://api.instagram.com/oauth/authorize?client_id=XXXXX&redirect_uri=XXXXX&scope=user_profile&response_type=code">
<img src="assets/images/instalogo.png" alt="Connetti a Instagram">
<p>Connect to Instagram</p>
</a>
The login form return always the same code, also with different accounts, resulting in error {"error_type": "OAuthException", "code": 400, "error_message": "This authorization code has been used"} in this next request:
$fields = array(
'client_id' => 'XXXXXX',
'client_secret' => 'XXXXXXXXX',
'grant_type' => 'authorization_code',
'redirect_uri' => 'https://www.XXXXXXX.it/connect.php',
'code' => $_GET['code']
);
$url = 'https://api.instagram.com/oauth/access_token';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_POST,true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_VERBOSE,true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
$result = curl_exec($ch);
if(curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch);
}
curl_close($ch);
$result = json_decode($result, true);
So my question is: Why am I getting always the same code despite different accounts?
I solved this issue by verifying the business or using the individual verification in the Facebook Developer Console.
Before using the API, you need to verify your identity clicking Settings > Basic settings then scroll to Individual verification or Business verification and complete all the steps.
I'm trying to connect to the Spotify API.
I get the authorization code with:
<?php
$redirect_uri = 'http%3A%2F%2Flocalhost%3A8000';
?>
Get code<br/><br/>
So far so good, I get the code. Then I try to exchange for a token with:
$redirect_uri = 'http%3A%2F%2Flocalhost%3A8000';
$url = 'https://accounts.spotify.com/api/token';
$fields = [
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => $redirect_uri,
'client_id' => $client_id,
'secret' => $secret
];
$fields_string = http_build_query($fields);
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
$result = curl_exec($ch);
And I've got every variation I can imagine of http://localhost:8000 whitelisted in the Spotify dashboard:
But I get this error:
result: {"error":"invalid_grant","error_description":"Invalid redirect URI"}
edit: What's weird is I CAN successfully link up with the implicit grant client side method, using the redirect URI http:%2F%2Flocalhost%3A8000 - so I know that this is whitelisted properly. I've used this URI in the code I posted above, and get the same error. I've also used every other combination I can think of, whether that's using :%2F%2F, %3A%2F%2F, a trailing slash, a trailing %3A etc etc. Same error every time!
Any ideas?
edit2: if I use $redirect_uri = 'http://localhost:8000'; i get a different error:
result: {"error":"invalid_request","error_description":""}
Now that you have stopped encoding the redirect_uri, it is complaining about invalid parameters.
As per the documentation, the client_id and secret aren't meant to sent along with the other parameters, they need to be added to the headers via the Authorization header:
https://developer.spotify.com/documentation/general/guides/authorization-guide/#2-have-your-application-request-refresh-and-access-tokens-spotify-returns-access-and-refresh-tokens
HEADER PARAMETER
Authorization
Base 64 encoded string that contains the client ID and client secret key.
The field must have the format:
Authorization: Basic <base64 encoded client_id:client_secret>
I seen answers for this in other posts but they are quite outdated and I know IG has updated their api since.
I followed their developer documentation but can not seem to make a request from my localhost.
$fields = array(
'client_id' => 'a2xxxxxxxxxxxxxxxxxxxxxxxxxxxxed',
'client_secret' => '3bxxxxxxxxxxxxxxxxxxxxxxxxxxxxx8f',
'grant_type' => 'authorization_code',
'redirect_uri' => 'http://localhost:8000/',
'code' => 'code'
);
$url = 'https://api.instagram.com/oauth/access_token';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_POST,true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
print $result; //your token
The above code is how I am making my request but I get the following error.
{"code": 400, "error_type": "OAuthException", "error_message": "Matching code was not found or was already used."}
I have disabled implicit oAuth, the app set up is pretty basic, with all the settings going to my personal site for the time being as the app is in sandbox mode anyway.
redirect_uri should be pointing to a public URL address, not localhost.
Turns out, I just had to logout of my Instagram account each time I wanted to request a new token.
I want to be able for my web site to post a message on the fan page of the website.
So I use this code I found:
<?php
require_once("assets/facebook.php");
$facebook = new Facebook(array(
'appId' => '471898006354908', // Fake
'secret' => 'd2f7fb2dbc0ab7f42bc1c4337ab041b1', // Fake
'cookie' => true
));
$access_token = $facebook->getAccessToken();
echo $access_token;
$msg = "testmsg";
$title = "testt";
$uri = "http://somesite.com";
$desc = "testd";
$pic = "http://static.adzerk.net/Advertisers/d18eea9d28f3490b8dcbfa9e38f8336e.jpg";
$attachment = array(
'access_token' => $access_token,
'message' => $msg,
'name' => $title,
'link' => $uri,
'description' => $desc,
'picture'=>$pic,
'actions' => json_encode(array('name' => $action_name,'link' => $action_link))
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://graph.facebook.com/me/feed');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $attachment);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //to suppress the curl output
$result = curl_exec($ch);
curl_close ($ch);
?>
Each time I execute the page it echoes me something like this:
471898006354908|d2f7fb2dbc0ab7f42bc1c4337ab041b1
But it don't post anything on my fan page ?
Any help please ?
If that is all the code you found, then you are missing one important part: the login process. It´s explained in detail in the docs: https://developers.facebook.com/docs/facebook-login/v2.4
Right now it seems that you are only using an App Access Token, but you need a User Access Token that is authorized with the publish_actions permission. Make sure you understand all the different Tokens, here are some links about those:
https://developers.facebook.com/docs/facebook-login/access-tokens
http://www.devils-heaven.com/facebook-access-tokens/
Don´t forget to read about Login Review too, if you want to go public with your App: https://developers.facebook.com/docs/facebook-login/review
Using your own CURL calls is perfectly fine btw, i would not suggest using the PHP SDK for small projects because that´s just overkill and the PHP SDK uses CURL too. After all it´s just a bunch of PHP Classes. Just make sure you don´t prefill the message parameter, because that´s not allowed according to the platform policy.
Use the Facebook API / SDK.
This is probably not permitted in ToS and actively prevented. They detect the agent and use other means to prevent you accomplishing this with cURL.
Or you need to at least jump through a couple authentication hoops probably to prevent abuse. Check this past post and please close this if you deem your question to be a dupe. Post to a Facebook user's wall with cURL PHP
Im building a small API and want to use oAuth2.0 for login and token handling.
I have followed this step by step guide to get started: https://bshaffer.github.io/oauth2-server-php-docs/cookbook/
Now this all works fine I can get my access_token by sending post request to the token.php from the link guide above:
//GET TOKEN
$params = array(
"client_id" => "testclient",
"client_secret" => "testpass",
"grant_type" => "client_credentials");
$test=curl_req($pageURL."/api/v1/"."token.php", $params, "POST");
echo "<pre>";
print_r($test);
This outputs, as espected:
stdClass Object
(
[access_token] => b53a01a66d20760a8afef05bf36951eeba6b886d
[expires_in] => 3600
[token_type] => Bearer
[scope] =>
)
Now I have the token and want to do a request to resource.php as in the example link above. But I want to do it with POST, not GET as in the step by step guide link above.
Is it possible to get the access_token verified with POST and if yes, how?
the command in the example is:
curl http://localhost/resource.php -d 'access_token=YOUR_TOKEN'
which actually issues a POST since CURL will revert to HTTP POST if the "-d" flag is provided, see the docs on "-d" at http://curl.haxx.se/docs/manpage.html
In general the OAuth server will be able to pickup to token if sent in any of the standardized ways, so a) in an "access_token" POST parameter, b) in an "access_token" query parameter (GET), or c) in the "Authorization: bearer" header. The last option is actually the preferred method since it prevents the access_token from mixing with user data (i.e. works also in non-REST environments) or ending up in logs.
I ended up sending the access_token and POST data this way
$params = array(
"client_id" => "testclient",
"client_secret" => "testpass",
"grant_type" => "client_credentials");
//GET TOKEN
$test=curl_req($pageURL."/api/v1/"."token.php", $params, "POST");
// ^-- Im not using the curl_req2 function below here
// Im using a function, from my old question here: https://stackoverflow.com/questions/13420952/php-curl-delete-request
echo "<pre>";
print_r($test);
$token = array(
"access_token" =>$test->access_token);
$data = array(
"Some" =>"data",
"More" =>"datatatat"
);
// GET ACCESS using POST and POST data
$test2=curl_req2($pageURL."/api/v1/User.php",$token, $data , "POST");
print_r($test2);
function curl_req2($url,$token,$data,$req)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $req);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $token['access_token']));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
//$result = json_decode($result);
curl_close($ch);
return $result;
}