Facebook extending user access token - facebook

Facebook documentation says offline_access is depreca ted.How do I extend the access token for 60 day?
I did enabled deprecated offline_access from advanced settings for app.

you can try to two ways:
1. enable the offline deprecation functionality, and grab the exchanged token value in available and then run cUrl functionality. After running the cUrl just pass the response value in var_dump().. you could see the access token and the expires date..
you will get different value for the opposite process of (1).

You can use https://developers.facebook.com/docs/howtos/login/extending-tokens/ for long lived access tokens, or https://developers.facebook.com/docs/howtos/login/login-as-app/ for non-expiring app access tokens. But you probably need the first.

function fb_renew_access_token($args=array()){
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".$args["app_id"]."&client_secret=".$args["app_secret"]."&grant_type=fb_exchange_token&fb_exchange_token=".$args["old_token"];
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_URL, $token_url);
$contents = curl_exec($c);
$err = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
$paramsfb = null;
parse_str($contents, $paramsfb);
return $paramsfb;
}
//to get the extended access token
$extended_access = fb_renew_access_token(array("app_id"=>"4545454544s45454545","app_secret"=>"sdfgds2fg4d2f54g5df4gdsdsfgdsfg54dfg","old_token"=>"54sdf54sd54f35asdgs4ghdsd5sh4d5trh4djhdfj45fdh"));

Related

How to call an external API in magento 2.2?

I am new to Magento 2. I need help in the following query.
How to call an external API on page load or on click of a button in Magento 2.2?
Do we need to create an observer for the same or is there a better way to do it. Will appreciate if any links are provided for step by step process.
First of all, we need to know how to call a basic API. Here is example about GET:
$externalAPI = 'https://your/external/api_url'
$ch = curl_init($externalAPI);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
$result = curl_exec($ch);
var_dump($result);
From the Magento side, we can use \Magento\Framework\HTTP\Client\Curl class:
$apiUrl = '';
$this->curl->addHeader('Content-Type', 'application/json');
$this->curl->get($apiUrl);
$body = $this->curl->getBody();
$httpCode = $this->curl->getStatus();
//Quick decoding body
$dataResponse = \Zend_Json::decode($body);
How to call an external API on page load or on click of a button in
Magento 2.2?
Do we need to create an observer for the same or is there
a better way to do it.
It depends on the requirements. When do you need to connect to API? Or just display it on the frontend?
Once you know when(or where?) you need to call the external API. You can choose the Plugin, Observer, or Ajax solution.

How to make a personal facebook app

I'm trying to make a facebook application that would do something on my own timeline. I can't understand facebook's own manual about this so i'm not really sure how things work there, so i'm hoping someone can clarify things here. I don't want anyone installing that application or somehow abusing it to post things on my timeline in my name. What steps should i take to prevent these things if possible?
Beyond what you have learned yet, you can use the php-sdk to authenticate and then check the visitors user id.
"i will edit in code as we discover what you are trying to accomplish, action wise."
php sdk example.
// init php sdk here.
// check if we have a user
// call api to get info about use
$user_profile = $facebook->api('/me');
// if we have a user, we can use that user id as a wrapper to filter content.
if($user_profile[id]==='000000000'){
// 000000000 is your facebook id for this example.
// i am logged in, and only i can see this.
// get some info, make a few posts, add photos etc; here.
}
cURL example
when you curl 'me', it ensures that it is the current session user, then when you compare that to your actual user id, you can gate "so to speak" content that only you can see and use.
cURL'ing to the me connection is only needed to create gate, you can do all your other curl calls after you know it is you doing it.
http://anotherfeed.com/curl.api.php?objid=me
here is an example, when i curl me, it looks for a logged in user, if there is an access token which for this example i excluded, it will return an array with my "me" info including my id.
Hard coded i will use $me=$curlresults[id] which is my user id returned by the session call.
to gate i simply
$me=$curlresults[id]
if($me==='myfacebookuserid'){
// do my other curl calls here, i know only i can see this.
}
Full cURL example.
get your user access token for your app from the token tool below, store it somewhere safe so you can pass it in via url param or session param.... https://developers.facebook.com/tools/access_token/
add your facebook user id where it says myfacebookuserid
to secure this you will need to pass the access token in with post, get or session.
for this example we will use the get method.
yourpage.php?user_token=youruseraccesstoken is how it is passed in this example.
$access_token = $_GET['user_token'];
$build = 'https://graph.facebook.com/me?'.$access_token.'';
function GetCH($url){
$ch=null;
if(!$ch){
$ch = curl_init();
}
curl_setopt($ch, CURLOPT_URL, "".$url."");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$return=curl_exec($ch);
if(!curl_errno($ch)){
return $return;
}else{
$fb_fail=curl_error($ch);
return $fb_fail;
}
curl_close($ch);
unset($ch);
};
$returned=GetCH($build);
$locs=json_decode($returned, true);
$meid=$locs[id];
if($meid==='myfacebookuserid'){
// do my other curl calls here, i know only i can see this.
}

Not receiving Google OAuth refresh token

I want to get the access token from Google. The Google API says that to get the access token, send the code and other parameters to token generating page, and the response will be a JSON Object like :
{
"access_token" : "ya29.AHES6ZTtm7SuokEB-RGtbBty9IIlNiP9-eNMMQKtXdMP3sfjL1Fc",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/HKSmLFXzqP0leUihZp2xUt3-5wkU7Gmu2Os_eBnzw74"
}
However, I'm not receiving the refresh token. The response in my case is:
{
"access_token" : "ya29.sddsdsdsdsds_h9v_nF0IR7XcwDK8XFB2EbvtxmgvB-4oZ8oU",
"token_type" : "Bearer",
"expires_in" : 3600
}
The refresh_token is only provided on the first authorization from the user. Subsequent authorizations, such as the kind you make while testing an OAuth2 integration, will not return the refresh_token again. :)
Go to the page showing Apps with access to your account:
https://myaccount.google.com/u/0/permissions.
Under the Third-party apps menu, choose your app.
Click Remove access and then click Ok to confirm
The next OAuth2 request you make will return a refresh_token (providing that it also includes the 'access_type=offline' query parameter.
Alternatively, you can add the query parameters prompt=consent&access_type=offline to the OAuth redirect (see Google's OAuth 2.0 for Web Server Applications page).
This will prompt the user to authorize the application again and will always return a refresh_token.
In order to get the refresh token you have to add both approval_prompt=force and access_type="offline"
If you are using the java client provided by Google it will look like this:
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, getClientSecrets(), scopes)
.build();
AuthorizationCodeRequestUrl authorizationUrl =
flow.newAuthorizationUrl().setRedirectUri(callBackUrl)
.setApprovalPrompt("force")
.setAccessType("offline");
I'd like to add a bit more info on this subject for those frustrated souls who encounter this issue. The key to getting a refresh token for an offline app is to make sure you are presenting the consent screen. The refresh_token is only returned immediately after a user grants authorization by clicking "Allow".
The issue came up for me (and I suspect many others) after I'd been doing some testing in a development environment and therefore already authorized my application on a given account. I then moved to production and attempted to authenticate again using an account which was already authorized. In this case, the consent screen will not come up again and the api will not return a new refresh token. To make this work, you must force the consent screen to appear again by either:
prompt=consent
or
approval_prompt=force
Either one will work but you should not use both. As of 2021, I'd recommend using prompt=consent since it replaces the older parameter approval_prompt and in some api versions, the latter was actually broken (https://github.com/googleapis/oauth2client/issues/453). Also, prompt is a space delimited list so you can set it as prompt=select_account%20consent if you want both.
Of course you also need:
access_type=offline
Additional reading:
Docs: https://developers.google.com/identity/protocols/oauth2/web-server#request-parameter-prompt
Docs: https://developers.google.com/identity/protocols/oauth2/openid-connect#re-consent
Discussion about this issue: https://github.com/googleapis/google-api-python-client/issues/213
I searched a long night and this is doing the trick:
Modified user-example.php from admin-sdk
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$authUrl = $client->createAuthUrl();
echo "<a class='login' href='" . $authUrl . "'>Connect Me!</a>";
then you get the code at the redirect url
and the authenticating with the code and getting the refresh token
$client()->authenticate($_GET['code']);
echo $client()->getRefreshToken();
You should store it now ;)
When your accesskey times out just do
$client->refreshToken($theRefreshTokenYouHadStored);
This has caused me some confusion so I thought I'd share what I've come to learn the hard way:
When you request access using the access_type=offline and approval_prompt=force parameters you should receive both an access token and a refresh token. The access token expires soon after you receive it and you will need to refresh it.
You correctly made the request to get a new access token and received the response that has your new access token. I was also confused by the fact that I didn't get a new refresh token. However, this is how it is meant to be since you can use the same refresh token over and over again.
I think some of the other answers assume that you wanted to get yourself a new refresh token for some reason and sugggested that you re-authorize the user but in actual fact, you don't need to since the refresh token you have will work until revoked by the user.
Rich Sutton's answer finally worked for me, after I realized that adding access_type=offline is done on the front end client's request for an authorization code, not the back end request that exchanges that code for an access_token. I've added a comment to his answer and this link at Google for more info about refreshing tokens.
P.S. If you are using Satellizer, here is how to add that option to the $authProvider.google in AngularJS.
In order to get the refresh_token you need to include access_type=offline in the OAuth request URL. When a user authenticates for the first time you will get back a non-nil refresh_token as well as an access_token that expires.
If you have a situation where a user might re-authenticate an account you already have an authentication token for (like #SsjCosty mentions above), you need to get back information from Google on which account the token is for. To do that, add profile to your scopes. Using the OAuth2 Ruby gem, your final request might look something like this:
client = OAuth2::Client.new(
ENV["GOOGLE_CLIENT_ID"],
ENV["GOOGLE_CLIENT_SECRET"],
authorize_url: "https://accounts.google.com/o/oauth2/auth",
token_url: "https://accounts.google.com/o/oauth2/token"
)
# Configure authorization url
client.authorize_url(
scope: "https://www.googleapis.com/auth/analytics.readonly profile",
redirect_uri: callback_url,
access_type: "offline",
prompt: "select_account"
)
Note the scope has two space-delimited entries, one for read-only access to Google Analytics, and the other is just profile, which is an OpenID Connect standard.
This will result in Google providing an additional attribute called id_token in the get_token response. To get information out of the id_token, check out this page in the Google docs. There are a handful of Google-provided libraries that will validate and “decode” this for you (I used the Ruby google-id-token gem). Once you get it parsed, the sub parameter is effectively the unique Google account ID.
Worth noting, if you change the scope, you'll get back a refresh token again for users that have already authenticated with the original scope. This is useful if, say, you have a bunch of users already and don't want to make them all un-auth the app in Google.
Oh, and one final note: you don't need prompt=select_account, but it's useful if you have a situation where your users might want to authenticate with more than one Google account (i.e., you're not using this for sign-in / authentication).
1. How to get 'refresh_token' ?
Solution: access_type='offline' option should be used when generating authURL.
source : Using OAuth 2.0 for Web Server Applications
2. But even with 'access_type=offline', I am not getting the 'refresh_token' ?
Solution: Please note that you will get it only on the first request, so if you are storing it somewhere and there is a provision to overwrite this in your code when getting new access_token after previous expires, then make sure not to overwrite this value.
From Google Auth Doc : (this value = access_type)
This value instructs the Google authorization server to return a
refresh token and an access token the first time that your application
exchanges an authorization code for tokens.
If you need 'refresh_token' again, then you need to remove access for your app as by following the steps written in Rich Sutton's answer.
I'm using nodejs client for access to private data
The solution was add the promp property with value consent to the settings object in oAuth2Client.generateAuthUrl function.
Here is my code:
const getNewToken = (oAuth2Client, callback) => {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
prompt: 'consent',
scope: SCOPES,
})
console.log('Authorize this app by visiting this url:', authUrl)
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
rl.question('Enter the code from that page here: ', (code) => {
rl.close()
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error while trying to retrieve access token', err)
oAuth2Client.setCredentials(token)
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err)
console.log('Token stored to', TOKEN_PATH)
})
callback(oAuth2Client)
})
})
}
You can use the online parameters extractor to get the code for generate your token:
Online parameters extractor
Here is the complete code from google official docs:
https://developers.google.com/sheets/api/quickstart/nodejs
I hope the information is useful
Setting this will cause the refresh token to be sent every time:
$client->setApprovalPrompt('force');
an example is given below (php):
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("email");
$client->addScope("profile");
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
For me I was trying out CalendarSampleServlet provided by Google. After 1 hour the access_key times out and there is a redirect to a 401 page. I tried all the above options but they didn't work. Finally upon checking the source code for 'AbstractAuthorizationCodeServlet', I could see that redirection would be disabled if credentials are present, but ideally it should have checked for refresh token!=null. I added below code to CalendarSampleServlet and it worked after that. Great relief after so many hours of frustration . Thank God.
if (credential.getRefreshToken() == null) {
AuthorizationCodeRequestUrl authorizationUrl = authFlow.newAuthorizationUrl();
authorizationUrl.setRedirectUri(getRedirectUri(req));
onAuthorization(req, resp, authorizationUrl);
credential = null;
}
Using offline access and prompt:consent worked well to me:
auth2 = gapi.auth2.init({
client_id: '{cliend_id}'
});
auth2.grantOfflineAccess({prompt:'consent'}).then(signInCallback);
In order to get new refresh_token each time on authentication the type of OAuth 2.0 credentials created in the dashboard should be "Other". Also as mentioned above the access_type='offline' option should be used when generating the authURL.
When using credentials with type "Web application" no combination of prompt/approval_prompt variables will work - you will still get the refresh_token only on the first request.
To get a refresh token using postman, here is an example of the configurations
Expected Response
now google had refused those parameters in my request (access_type, prompt)... :( and there is no "Revoke Access" button at all. I'm frustrating because of getting back my refresh_token lol
UPDATE:
I found the answer in here :D you can get back the refresh token by a request
https://developers.google.com/identity/protocols/OAuth2WebServer
curl -H "Content-type:application/x-www-form-urlencoded" \
https://accounts.google.com/o/oauth2/revoke?token={token}
The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.
If the revocation is successfully processed, then the status code of the response is 200. For error conditions, a status code 400 is returned along with an error code.
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010_000;
use utf8;
binmode STDOUT, ":encoding(utf8)";
use Text::CSV_XS;
use FindBin;
use lib $FindBin::Bin . '/../lib';
use Net::Google::Spreadsheets::V4;
use Net::Google::DataAPI::Auth::OAuth2;
use lib 'lib';
use Term::Prompt;
use Net::Google::DataAPI::Auth::OAuth2;
use Net::Google::Spreadsheets;
use Data::Printer ;
my $oauth2 = Net::Google::DataAPI::Auth::OAuth2->new(
client_id => $ENV{CLIENT_ID},
client_secret => $ENV{CLIENT_SECRET},
scope => ['https://www.googleapis.com/auth/spreadsheets'],
);
my $url = $oauth2->authorize_url();
# system("open '$url'");
print "go to the following url with your browser \n" ;
print "$url\n" ;
my $code = prompt('x', 'paste code: ', '', '');
my $objToken = $oauth2->get_access_token($code);
my $refresh_token = $objToken->refresh_token() ;
print "my refresh token is : \n" ;
# debug p($refresh_token ) ;
p ( $objToken ) ;
my $gs = Net::Google::Spreadsheets::V4->new(
client_id => $ENV{CLIENT_ID}
, client_secret => $ENV{CLIENT_SECRET}
, refresh_token => $refresh_token
, spreadsheet_id => '1hGNULaWpYwtnMDDPPkZT73zLGDUgv5blwJtK7hAiVIU'
);
my($content, $res);
my $title = 'My foobar sheet';
my $sheet = $gs->get_sheet(title => $title);
# create a sheet if does not exit
unless ($sheet) {
($content, $res) = $gs->request(
POST => ':batchUpdate',
{
requests => [
{
addSheet => {
properties => {
title => $title,
index => 0,
},
},
},
],
},
);
$sheet = $content->{replies}[0]{addSheet};
}
my $sheet_prop = $sheet->{properties};
# clear all cells
$gs->clear_sheet(sheet_id => $sheet_prop->{sheetId});
# import data
my #requests = ();
my $idx = 0;
my #rows = (
[qw(name age favorite)], # header
[qw(tarou 31 curry)],
[qw(jirou 18 gyoza)],
[qw(saburou 27 ramen)],
);
for my $row (#rows) {
push #requests, {
pasteData => {
coordinate => {
sheetId => $sheet_prop->{sheetId},
rowIndex => $idx++,
columnIndex => 0,
},
data => $gs->to_csv(#$row),
type => 'PASTE_NORMAL',
delimiter => ',',
},
};
}
# format a header row
push #requests, {
repeatCell => {
range => {
sheetId => $sheet_prop->{sheetId},
startRowIndex => 0,
endRowIndex => 1,
},
cell => {
userEnteredFormat => {
backgroundColor => {
red => 0.0,
green => 0.0,
blue => 0.0,
},
horizontalAlignment => 'CENTER',
textFormat => {
foregroundColor => {
red => 1.0,
green => 1.0,
blue => 1.0
},
bold => \1,
},
},
},
fields => 'userEnteredFormat(backgroundColor,textFormat,horizontalAlignment)',
},
};
($content, $res) = $gs->request(
POST => ':batchUpdate',
{
requests => \#requests,
},
);
exit;
#Google Sheets API, v4
# Scopes
# https://www.googleapis.com/auth/drive View and manage the files in your Google D# # i# rive
# https://www.googleapis.com/auth/drive.file View and manage Google Drive files and folders that you have opened or created with this app
# https://www.googleapis.com/auth/drive.readonly View the files in your Google Drive
# https://www.googleapis.com/auth/spreadsheets View and manage your spreadsheets in Google Drive
# https://www.googleapis.com/auth/spreadsheets.readonly View your Google Spreadsheets
My solution was a bit weird..i tried every solution i found on internet and nothing. Surprisely this worked: delete the credentials.json, refresh, vinculate your app in your account again. The new credentials.json file will have the refresh token. Backup this file somewhere.
Then keep using your app until the refresh token error comes again. Delete the crendetials.json file that now is only with an error message (this hapenned in my case), then paste you old credentials file in the folder, its done!
Its been 1 week since ive done this and had no more problems.
Adding access_type=offline to the authorisation Google authorisation URL did the trick for me. I am using Java and Spring framework.
This is the code that creates the client registration:
return CommonOAuth2Provider.GOOGLE
.getBuilder(client)
.scope("openid", "profile", "email", "https://www.googleapis.com/auth/gmail.send")
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth?access_type=offline")
.clientId(clientId)
.redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")
.clientSecret(clientSecret)
.build();
The important part here is the authorization URI, to which ?access_type=offline is appended.

Delete requests returns true, but request still exists?

Possible answer or bug: Using the user access token seems to work, it deletes the request and will throw an error when trying to read it in the future, but it still exists in the graph and providing apptoken still shows it, and for some reason wouldn't delete it. Seems contrary to documentation, but changing apptoken to access token seemed to at least provide a workaround for me.
First, the code I'm using (as the one in the documentation always returned an entity not visible by user type message)
function do_delete_request($url, $optional_headers = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//include array of additional headers
if (count($optional_headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $optional_headers);
}
return curl_exec($ch);
}
$full_request_id = build_full_request_id($request_id, $user_id);
$delete_url = "https://graph.facebook.com/" .$full_request_id. "?access_token=".$apptoken;
$result = do_delete_request($delete_url);
I'm sorry if that's messy, I don't know how to format stuff here. I'm at a loss after a lot of googling, I never ask this stuff.
$result returns true, over and over again. Graph explorer shows the request still exists.
By deleting it, does that just mean I remove it from the requests interface for a user? Or am I doing something wrong in my delete process?
I need a way to tell whether or not a request has been accepted already or not. Thanks for any help.
Facebook sends the user to your app with the Request ID(s) in the URL, that's how you tell when a request has been accepted. It's up to you to check for a process a response to a request.
https://apps.facebook.com/[app_name]/?request_ids=[request_ids]
As far as delete not working, is the request still their after some time? Facebook, and many busy sites, do heavy caching so things like delete may not be processed immediately.

Intermittent bad Facebook app access_token

I'm creating test users in Facebook for my application. It works sometimes. When it doesn't, the error occurs on this call:
function getTestAccounts($fb, $a) {
$s = urlencode($a);
**$accounts = $fb->api("/{$fb->getAppId()}/accounts/test-users?access_token=$s");**
if( isset($accounts['data']) )
return $accounts;
else
return null;
}
Error is:
Uncaught OAuthException: (#15) This method must be called with an app access_token.
Previously I've obtained the token with this function:
function getAppAccessToken($fb) {
$access_token_url = "https://graph.facebook.com/oauth/access_token";
$parameters = "grant_type=client_credentials&client_id=" . $fb->getAppId() . "&client_secret=" . $fb->getApiSecret() . "&junk=1";
return file_get_contents($access_token_url . "?" . $parameters);
}
When I output the offending token, it looks something like this and does not change (should it?)
access_token=229234510434203|TK2UDoGCPthCBeDIvhRIPkSG8Wk
I've tried clearing cookies. That seemed to work but might have been coincidental with something else because it does not now.
I assume the access token returned from FB changes but it's always coming back the same.
Mark
for a user access token i use the below, where the number is my app id. "used with php-sdk"
$access_token = $_SESSION['fb_135669679827333_access_token'];
for an application access token i use cURL
$app_access_token = GetCH();
function GetCH(){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
if(substr($url,0,8)=='https://'){
// The following ensures SSL always works. A little detail:
// SSL does two things at once:
// 1. it encrypts communication
// 2. it ensures the target party is who it claims to be.
// In short, if the following code is allowed, CURL won't check if the
// certificate is known and valid, however, it still encrypts communication.
curl_setopt($ch,CURLOPT_HTTPAUTH,CURLAUTH_ANY);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
}
$sendCH = curl_exec($ch);
curl_close($ch);
return $sendCH;
};
Let me know if this helps.
I made a greenhorn mistake. What I failed to notice was that this problem was only occurring after I opened another browser tab and logged to Facebook as myself or a test user. The new Facebook session was interfering with the API.
I guess the API uses the access token of the logged on user instead of what's passed in the request. Kind of obvious once you understand it!
Hope this helps the next person :-)