Like button to a page photo - php

Can you tell me with steps how can I do a like button in my site (php) to like a page photo on facebook?
I know that I have to use the GRAPH API and have to do the POST via HTTP to /likes .. but I dont know how can I do it with PHP code.
Somebody have an example?
Thank you

As long as you have obtained the publish_stream permission from the user you can like any photo you need to. If you are attempting to like the photo as a page be sure you have an access_token for the page (obtained via the /accounts connection on the user account).
Once you have the access token the like is as simple as issuing an HTTP POST to a URL that looks similar to this:
https://graph.facebook.com/PHOTO_ID/likes?access_token=ACCESS_TOKEN
Photo_ID = Photo ID in Facebook
Access_Token = Access token obtained from Facebook with the publish_stream permission.
UPDATE
PHP Sample Code based on PHP Form CURL Post
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://graph.facebook.com/PHOTO_ID/likes");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
$data = array(
'Access_Token' => 'token_value'
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
I would check this though as I'm not sure how accurate it is since I don't normally code PHP. In any manner, the post should be a raw HTTP POST request.

Fabio here is the php post snippet that i was able to get working. Snippet includes a curl to get application access token and the api post to like an object, in this case a post on my app.
The Sample post is here: Shows the post to be liked
https://shawnsspace.com/plugins/TimeLinePost.php?pageid=135669679827333&postid=135669679827333_151602784936066&type=feed&fh=750
The Like Page is here: Should Return whether the user likes or not, or login if not connected.
https://shawnsspace.com/plugins/TheLike.php?postid=135669679827333_151602784936066
Getting the Application Access Token.
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']);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT_MS,20000);
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;
};
$app_access_token = GetCH();
Looking in url for postid parameter then liking id
if($_GET['postid']){
$postid = $_GET['postid'];
}else{
$postid = '135669679827333_151602784936066';
}
if($user){
$pageLike = $facebook->api('/'.$postid.'/likes?access_token='.$access_token.'&method=post', 'POST');
}

You can get permissions by building an array of perms for login url. below i am requesting read_stream,publish_stream,publish_actions,offline_access in the scope for permissions.
NOTE: app access token needed for logout url.
<?php
$url = (!empty($_SERVER['HTTPS'])) ? 'https://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
require './src/facebook.php';
$facebook = new Facebook(array(
'appId' => 'APPID',
'secret' => 'APP-SECRET',
'cookie' => true, // enable optional cookie support
));
$user = $facebook->getUser();
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
//$pageInfo = $facebook->api('/'.$pageid.'?access_token='.$_SESSION['fb_112104298812138_access_token].');
//$pageInfoUser = $user_profile[id];
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
/* */
if ($user) {
$logoutUrl = $facebook->getLogoutUrl();
} else {
$params = array(
scope => 'read_stream,publish_stream,publish_actions,offline_access',
redirect_uri => $url
);
$loginUrl = $facebook->getLoginUrl($params);
}
$access_token = $_SESSION['fb_135669679827333_access_token'];
?>
<?php
if(!$user){
echo ' : Login ';
}else{
echo 'Logout';
}
?>

Related

PHP Laravel Callback upon API authentication

I am trying to implement a call back method in PHP. I am successfully calling an instagram API to authorise the user but I do not know how to capture the token after the user authorises.
Below is my code:
public function oAuthBasic()
{
$instagramBasic = new InstagramBasicDisplay([
'appId' => 'xxx',
'appSecret' => 'xxx',
'redirectUri' => 'xxx'
]);
session()->forget('instagramErrorMessage');
$faceBookLoginUrl = $instagramBasic->getLoginUrl();
return response()->json(['redirectUrl' => $faceBookLoginUrl]);
}
This successfully brings up the sign in pop up. However after authorisation, how can I capture the user access token?
Any help is greatly appreciated.
I managed to fix the issue with the help of #CBore's comment:
Created a new route in my web.php
Route::get('linkinstagramBasic','InstagramController#linkBasic')->name('instagram.linkBasic');
Included the URL under Valid OAuth Redirect URIs on facebook app settings page.
Finally wrote the callback:
/*
* Function that works as the call back after Instagram basic display api authorisation
* Get the code and call access_token API
* AUTHOR : DON
* DATE : 12/10/2022
*/
public function linkBasic(InstagramLinkRequest $instagramRequest) {
if (isset($_GET['code'])) {
// Get the OAuth callback code
$code = $_GET['code'];
$ig_atu = "https://api.instagram.com/oauth/access_token";
$ig_data = [];
$ig_data['client_id'] = Config::get('instagram_basic.app_id');
$ig_data['client_secret'] = Config::get('instagram_basic.app_secret');
$ig_data['grant_type'] = 'authorization_code';
$ig_data['redirect_uri'] = Config::get('instagram_basic.redirect_uri');
$ig_data['code'] = $code;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ig_atu);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($ig_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$ig_auth_data = curl_exec($ch);
curl_close($ch);
$ig_auth_data = json_decode($ig_auth_data, true);
dd($ig_auth_data);
//$accessTok = $ig_auth_data['access_token'];
//$UID = $ig_auth_data['user_id'];
//echo "<script>window.close();</script>";
}
}

Get access token using refresh token

I am currently implementing OAuth2 using thephpleague/oauth2 library. I have already added the refresh token grant and the access token response already contains the refresh token. However, I don't have any idea how to use that refresh token to get a new access token.
I checked the documentation but I don't see anything about it. The oauth2-client library has methods for it but I'm not going to use that.
My code for the refresh token grant:
$server->setRefreshTokenStorage(new RefreshTokenStorage);
$refreshTokenGrant = new \League\OAuth2\Server\Grant\RefreshTokenGrant();
$authCodeGrant = new \League\OAuth2\Server\Grant\AuthCodeGrant();
$server->addGrantType($authCodeGrant);
$server->addGrantType($refreshTokenGrant);
$response = $server->issueAccessToken();
My question is how can I test that using the refresh token, I can retrieve a new access token? Do I have to implement a new endpoint different from the one that's used by the authorization code grant?
Here is my code for getting the token. Any comments?
public function actionToken(){
$authCodeModel = new \app\models\OAuth_Auth_Codes;
if(!isset($_POST['code'])){
throw new \yii\web\HttpException(400,"Required parameter \'code\' is missing or invalid.");
}
$result = $authCodeModel->find()->where(['authorization_code' => trim($_POST['code'])])->one();
if(!empty($result)){
$user_id = $result->user_id;
$session2 = new Session();
$session2->open();
$server = new AuthorizationServer;
$server->setSessionStorage(new SessionStorage);
$server->setAccessTokenStorage(new AccessTokenStorage);
$server->setClientStorage(new ClientStorage);
$server->setScopeStorage(new ScopeStorage);
$server->setAuthCodeStorage(new AuthCodeStorage);
$server->setRefreshTokenStorage(new RefreshTokenStorage);
$refreshTokenGrant = new \League\OAuth2\Server\Grant\RefreshTokenGrant();
$authCodeGrant = new \League\OAuth2\Server\Grant\AuthCodeGrant();
$server->addGrantType($authCodeGrant);
$server->addGrantType($refreshTokenGrant);
$response = $server->issueAccessToken();
$model = new \app\models\OAuth_Access_Tokens();
$accessTokenModel = $model->find()->where(['access_token' => $response['access_token']])->one();
$accessTokenModel->setAttribute('user_id',''.$user_id);
$accessTokenModel->save(FALSE);
return json_encode($response);
}
else{
throw new \yii\web\UnauthorizedHttpException("You have provided an invalid authorization code.");
}
}
Using the cURL support in PHP it would be:
$postData = array(
"grant_type" => "refresh_token",
"client_id" => $clientID,
"client_secret" => $clientSecret,
"refresh_token" => $refreshToken
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $tokenEndpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
curl_close($ch);
$r = json_decode($response);
echo $r->access_token;
Edit:
For server side examples see: https://github.com/thephpleague/oauth2-server/blob/master/tests/unit/Grant/RefreshTokenGrantTest.php, e.g.:
$server = new AuthorizationServer();
$grant = new RefreshTokenGrant();
$server->addGrantType($grant);
$server->issueAccessToken();

API LinkedIn - Error on getaccesstoken()

I m trying to get access to the linkedin api but like a lot of people, fail everytime and have this following message of error :
missing required parameters, includes an invalid parameter value, parameter more then once. : Unable to retrieve access token : appId or redirect uri does not match authorization code or authorization code expired
I've cheked the hosting server's timestamp and i revoke and create the token on the app admin before i launch the code (the faster i can due to the short life time of the authorization code given).
Here's my index file and just after the functions i use :
<?php
// VARS
define('API_KEY', 'xxxxxxxxxx');
define('API_SECRET', 'xxxxxxxxxx');
define('REDIRECT_URI', 'https://' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME']);
define('SCOPE', 'r_basicprofile');
session_name('linkedin');
session_start();
include('lib/functions.php');
// OAuth 2 Control Flow
if (isset($_GET['error'])) {
// LinkedIn returned an error
print $_GET['error'] . ': ' . $_GET['error_description'];
exit;
}
elseif (isset($_GET['code'])) {
// User authorized your application
getAccessToken();
}
else {
if ((empty($_SESSION['expires_at'])) || (time() > $_SESSION['expires_at'])) {
// Token has expired, clear the state
$_SESSION = array();
}
if (empty($_SESSION['access_token'])) {
// Start authorization process
getAuthorizationCode();
}
}
// Congratulations! You have a valid token. Now fetch your profile
$user = fetch('GET', '/v1/people/~:(firstName,lastName)');
print "Hello $user->firstName $user->lastName.";
?>
And the functions :
<?php
function getAuthorizationCode() {
$params = array('response_type' => 'code',
'client_id' => API_KEY,
'scope' => SCOPE,
'state' => uniqid('', true), // unique long string
'redirect_uri' => REDIRECT_URI
);
// Authentication request
$url = 'https://www.linkedin.com/uas/oauth2/authorization?'.http_build_query($params);
// Needed to identify request when it returns to us
$_SESSION['state'] = $params['state'];
// Redirect user to authenticate
header("Location: $url");
exit;
}
function getAccessToken() {
$params = array('grant_type' => 'authorization_code',
'client_id' => API_KEY,
'client_secret' => API_SECRET,
'code' => $_GET['code'],
'redirect_uri' => REDIRECT_URI
);
var_dump($params);
// Access Token request
//$url = 'https://www.linkedin.com/uas/oauth2/accessToken?' . http_build_query($params);
$url = 'https://www.linkedin.com/uas/oauth2/accessToken';
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
curl_setopt($c, CURLOPT_POST,true);
curl_setopt($c, CURLOPT_POSTFIELDS, http_build_query($params));
$response = curl_exec($c); // on execute la requete
curl_close($c);
// Native PHP object, please
$token = json_decode($response);
// Store access token and expiration time
$_SESSION['access_token'] = $token->access_token; // guard this!
$_SESSION['expires_in'] = $token->expires_in; // relative time (in seconds)
$_SESSION['expires_at'] = time() + $_SESSION['expires_in']; // absolute time
// DEBUG //
echo 'Retour get access token : </br>';
var_dump($token);
echo '</br>--------------------------</br></br>';
// ! DEBUG //
return true;
}
function fetch($method, $resource, $body = '') {
$params = array('oauth2_access_token' => $_SESSION['access_token'], 'format' => 'json');
// Need to use HTTPS
//$url = 'https://api.linkedin.com' . $resource . '?' . http_build_query($params);
// Tell streams to make a (GET, POST, PUT, or DELETE) request
$url = 'https://api.linkedin.com' . $resource;
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
curl_setopt($c, CURLOPT_POSTFIELDS,http_build_query($params));
$response = curl_exec($c);
curl_close($c);
// DEBUG //
echo 'Retour fetch : </br>';
var_dump($response);
echo '</br>--------------------------</br></br>';
// ! DEBUG //
// Native PHP object, please
return json_decode($response);
}
?>
I tried many things but it never works. If someone see the issue tnaks a lot in advance.
Thanks
I have faced the same problem and my issue was caused by http_build_query() function, http://www.php.net/manual/en/function.http-build-query.php
for some reason it tries to encode the parameters to build a query string that will be used by the Linkedin services, if you try to construct the string manually it will pass and it will work.
and actually I reached this page while searching to figure out if its a PHP version issue or maybe the function http_build_query() take in account some environment variables like encoding and locale settings.
not sure but this fixed my issue.

Facebook graph login - website integration, failed get token

I have read about facebook opengraph connection - as far as I have understood, the login procedure is made within 3 steps:
Get the login url from the facebook api call in order to create a custom login button
Upon clicking on the link we are redirected to the facebook login page
Do the actual login and get redirected to the site we have defined in the app facebook developer page
In this page we have to deal with the actual result. Here comes the problem: I've understood that we have to use the token and make a new request to the fb page in order to validate the token (see below).
After this, I assume we get the user actual details but I never manage to execute this token request and therefore I'm not sure in how to proceed.
$ch = curl_init("http://graph.facebook.com/oauth/access_token? client_id=".$facebook_config['appId']."
&client_secret=".$facebook_config['secret']."
&redirect_uri=".urlencode(SITE_DOMAIN)."/facebook_login_processor.php
&code=".$_GET['code']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 30000);
$data = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
curl_close($ch);
if ($curl_errno > 0)
{
echo "cURL Error ($curl_errno): $curl_error\n";
}
else
{
echo $data;
}
I'm getting an error regarding the redirect_uri - somehow it is not getting validated.
{"error":{"message":"Missing redirect_uri parameter.","type":"OAuthException","code":191}}
Bear in mind that I'm trying this on a non public website (domain is only registred in the server and in my hosts file). Does this impose a problem?
I appreciate any help and thank you for your attention and help
Ricardo
Ps.: sorry about any error - I'm on the phone
Based on facebook php sdk, the script below simply works well on my website.
&lt?php
require_once "lib/facebook.php";
$scope = "create_note,email friends_groups,friends_interests";
$redirecturl = "https://www.mysite.com/callback.php";
$facebook = new Facebook(array('appId' => APP_ID,'secret' => APP_SECRET));
$authurl = $facebook->getLoginUrl( array( 'scope' => $scope, 'redirect_uri' => $redirecturl );
header("Location:$authurl");
?>
then on callback.php
&lt?php
require_once "lib/facebook.php";
$facebook = new Facebook(array('appId' => APP_ID,'secret' => APP_SECRET));
$user = $facebook->getUser();
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
if (!empty($user_profile)) {
print_r($user_profile);
// or do something here
}
}
?>
Note: You should define APP_ID and APP_SECRET.

Graph API wont display profile feed

I'm using the facebook API to get my wall feed using the graph API.
<?php
require_once('facebook.php');
// Create our Application instance (replace this with your appId and secret).
$facebook = new Facebook(array(
'appId' => '188687744521977',
'secret' => 'c2c3692845602812f473436d1da95014',
'cookie' => true
));
// Get User ID
$user = $facebook->getUser();
// We may or may not have this data based on whether the user is logged in.
// If we have a $user id here, it means we know the user is logged into
// Facebook, but we don't know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.
if($user)
{
try
{
// Proceed knowing you have a logged in user who's authenticated.
$access_token = $_SESSION['fb_188687744521977_access_token'];
$user_profile = $facebook->api('/me');
$likes = $facebook->api('/me?fields=feed,likes');
$friends = $facebook->api('/me/friends');
$feed = 'https://graph.facebook.com/me/feed? access_token='.$access_token.'';
} catch (FacebookApiException $e)
{
error_log($e);
$user = null;
}
}
// Login or logout url will be needed depending on current user state.
if($user)
{
$logoutUrl = $facebook->getLogoutUrl();
} else
{
$loginUrl = $facebook->getLoginUrl();
}
// Save the user's info as variables
$full_name = $user_profile['name'];
$first_name = $user_profile['first_name'];
$last_name = $user_profile['last_name'];
$relationship = $user_profile['relationship_status'];
$partner_id = $user_profile['significant_other_id'];
$id = $user_profile['id'];
$link = $user_profile['link'];
function get_url($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$tmp = curl_exec($ch);
curl_close($ch);
return $tmp;
}
$wall = get_url($feed);
print_r(json_decode($wall, true));
?>
However, an empty array is displayed. Any suggestions?
You should definitly try to find a better solution for handling the access token! Where are you setting this $_SESSION['fb_..._access_token']? Who says that 188687744521977 is always the userid of the logged in user? Why do you have spaces in your feed url?
The first thing you should do is delete the json_decode() and just var_dump() the $wall. I think your access token is not valid, maybe you also get a 401 Unauthorized or 403 Forbidden response?

Categories