Instagram API access token request fail - php

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.

Related

How to make POST (API) request with cookies inside controller | Laravel 9.x

I'm working with Omada Controller (External Portal Server). That is, to register users through the EAP. The device must be allowed to use WiFi.
I use following documentation:
https://www.tp-link.com/ru/support/faq/3231/
I tested the requests through Postman. Everything is working. However, it is necessary to send a cookie in the request to authorize the device after logging in.
I wrote the following code in Laravel. but cookies are not being stored or sent.
public function AuthFree(Request $req)
{
$inputs = $req->all();
//IP Address of Controller
$endPoint = 'https://CONTROLLER_API:PORT/CONTROLLER_ID/api/v2/hotspot/extPortal/auth';
$operatorData = self::getCSRFToken();
$csrfToken = $operatorData->object()->result->token;
$cookies = $operatorData->cookies()->getCookieByName('TPEAP_SESSIONID')->toArray();//->getValue();
$deviceBody = [
'clientMac' => $inputs['clientMac'],
'apMac' => $inputs['apMac'],
'ssidName' => $inputs['ssidName'],
'radioId' => $inputs['radioId'],
'time' => 1859960742,
'authType' => 4,
];
$authDevice = Http::withCookies($cookies, $endPoint)
->timeout(30)->withOptions([
'verify' => false,
])
->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Csrf-Token' => $csrfToken,
])
->post($endPoint, $deviceBody);
dd($authDevice);
}
//Login operator.
public function getCSRFToken()
{
$authOperator = Http::accept('application/json')->timeout(15)->withOptions([
'verify' => false,
])
->post('https://IP:PORT/ID/api/v2/hotspot/login', [
'name' => 'USERNAME',
'password' => 'PASSWORD',
]);
return $authOperator;
}
Also i wrote as following code:
$ch = curl_init();
// Set return to a value, not return to page
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Set up cookies.
curl_setopt($ch, CURLOPT_COOKIEJAR, request()->cookie('TPEAP_SESSIONID'));
curl_setopt($ch, CURLOPT_COOKIEFILE, request()->cookie('TPEAP_SESSIONID'));
// Allow Self Signed Certs
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// API Call
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($authInfo));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$res = curl_exec($ch);
$resObj = json_decode($res);
return $resObj;
But this also returns error.
The operator enters the system and receives a token through the getCSRFToken function mentioned above. A COOKIE is returned along with the token. I need to send TOKEN and COOKIES together to authorize the device.
Meanwhile, the getCSRFToken function is running and returning tokens. But authDevice is returning an error. Because it can't get Header and Cookies.
My question is: How can I save the cookies and how can I add them to the request and send them?
Is there something wrong with the code I wrote?
As far as I know CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE need the same file, so something as:
curl_setopt($ch, CURLOPT_COOKIEJAR, $temp_cookie_file);
curl_setopt($ch, CURLOPT_COOKIEFILE,$temp_cookie_file);
I'm struggling with the setup of an external portalt too.
Get a token, I can see the TPEAP_SESSIONID in the '$temp_cookie_file', but get in the authorization step: "[errorCode] => -1 [msg] => General error."

Instagram Basic Display API - This authorization code has been used

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.

PHP upload to a imgur Album does not work?

im trying to upload to my imgur Account's album, however, the upload works, but it looks like its gonna uploaded as anonym/public?
here's my code:
<?php
$client_id = "465xxx8c44294";
$image = file_get_contents("../images/d4487317c3xxx93210b293c2e.jpg");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
//curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => base64_encode($image)));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => base64_encode($image), 'album' => 'nqxxxGE'));
$reply = curl_exec($ch);
curl_close($ch);
$reply = json_decode($reply);
printf('<img height="180" src="%s" >', $reply->data->link);
any advice?
If you want to add image to album, according doc, you need to pass album id. Make sure you've generated token that has access to secret albums.
Here you can find some tips about tokens.
curl_setopt($ch, CURLOPT_POSTFIELDS,
array(
'image' => base64_encode($image),
'album' => '5' // 5 - your album id
)
);
You can check you albums id using this api.
To refresh token:
If a user has authorized their account but you no longer have a valid access_token for them, then a new one can be generated by using the refresh_token.
To obtain a new access token, your application performs a POST to https://api.imgur.com/oauth2/token. The request must include the following parameters to use a refresh token:
refresh_token: The refresh token returned from the authorization code exchange
client_id: The client_id obtained during application registration
client_secret: The client secret obtained during application registration.
grant_type: As defined in the OAuth2 specification, this field must contain a value of: refresh_token.
As long as the user has not revoked the access granted to your application, the response includes a new access token. A response from such a request is shown below:
{
"access_token":"5c3118ebb73fbb275945ab340be60b610a3216d6",
"refresh_token":"d36b474c95bb9ee54b992c7c34fffc2cc343d0a7",
"expires_in":3600,
"token_type":"Bearer",
"account_username":"saponifi3d"
}
Add the refresh part at the start of your script. Something like:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/oauth2/token');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'refresh_token' => $refreshToken, // Your refresh_token
'client_id' => $client_id,
'client_secret' => $clientSecret, //Your client_secret
'grant_type' => 'refresh_token'
]);
//Keep in mind that refreshToken and clientSecret are obtained during registration.
$reply = curl_exec($ch);
curl_close($ch);
$reply = json_decode($reply);
$accessToken = $reply->access_token;

Cannot refresh token from google api OAuth2

Here is my php script RefreshToken.php
<?php
$url = 'https://accounts.google.com/o/oauth2/token';
$post_data = array(
'code' => 'xxxxxxxx',
'client_id' => 'xxxxxxxxxxx',
'client_secret' => 'xxxxxxxxxxxxx',
'redirect_uri' => 'http://localhost/googleapi/AuthenticationCode.php',
'grant_type' => 'authorization_code',
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$token = json_decode($result);
echo $token->refresh_token . "\n";
?>
Run PHP CLI
php -q RefreshToken.php
PHP Notice: Undefined property: stdClass::$refresh_token in /var/www/googleapi/RefreshToken.php on line 20
The refresh_token is not returned by default in Google OAuth2.
The request for an authorization code requires an extra parameter (access_type): then refresh token will be returned with access_token.
Other unusual behaviour: the refresh_token is returned only one time for a user. If, for some reason, refresh_token is lost for that user, then user will need to open Google Account Security Settings page and drop access for your app. And this is not enough: your app will need to pass more one params (approval_prompt equals true) to indicate we're forcing the request for a new refresh_token.
More info: https://developers.google.com/accounts/docs/OAuth2WebServer#offline)

curl php cannot get access token from google. Curl returns nothing

UPDATE
If I perform a curl_error() this gets returned
Protocol https not supported or disabled in libcurl
if I send a curl request via the command line I get an access token fine:
curl --data "code=removed&client_id=removed&client_secret=removed&redirect_uri=https://group.cs.cf.ac.uk/group3/oAuth2redirect.php&scope=https://www.googleapis.com/auth/calendar&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token
However when I try and do this via php curl just returns nothing
$code = $_GET['code'];
$client_id = "removed";
$client_secret = "removed";
$redirectUri = "https://group.cs.cf.ac.uk/group3/oAuth2redirect.php";
$scope = "https://www.googleapis.com/auth/calendar";
$grant_type = "authorization_code";
$url = "https://accounts.google.com/o/oauth2/token/";
$params = array(
'code' => $code,
'client_id' => $client_id,
'client_secret' => $client_secret,
'redirect_uri' => $redirectUri,
'scope' => $scope,
'grant_type' => $grant_type
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($ch);
curl_close($ch);
print_r($response);
does anyone know why this is happerning, I think it may to do with headers however I really can't work this out.
any help would be awesome
edit
using Google's library for oauth2 is not an option
I've solved the problem now. It turns out curl was not set to be able do to ssl requests (as evident as curl_error() was returning Protocol https not supported or disabled in libcurl.
I think ssl creating problem. Google is https, so it need set_opt("CURLOPT_SSL_VERIFYPEER",val) also, for more details visit, http://www.php.net/manual/en/function.curl-setopt-array.php beside other things, this may be problem.

Categories