I want to find the list of friends of Google+ user who have authorized the app without asking for authorization again.
For example: Once the user login using the Google+ to my website, I store the auth token, code, Google+ user id in the db.
So once that is done I want to find the list of users friends in his circle.
I managed to get the first part working and it saves the auth token, code, Google+ user id in the db.
But in the second case i.e. finding the list of users friends, I again get a the screen where user have to authorize the app.
Can someone please help me in this?
Also is it possible to get all the user details in offline mode like using the auth token, code, Google+ user id which is in the db?
Initial code(login):
require_once __DIR__.'/social-api/google/Google_Client.php';
require_once __DIR__.'/social-api/google/contrib/Google_PlusService.php';
$this->sn_obj = new Google_Client($google_app_id, $google_secret_key, $call_back_url);
$this->plus_obj = new Google_PlusService($this->sn_obj);
$this->sn_obj->setRedirectUri($call_back_url);
$this->sn_obj->setState($redirect_url);
$requestVisibleActions = array('http://schemas.google.com/AddActivity','http://schemas.google.com/ReviewActivity');
$this->sn_obj->setRequestVisibleActions($requestVisibleActions);
$this->sn_obj->setAccessType('offline');
$this->sn_obj->setScopes(array('https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/plus.login'));
$this->sn_obj->createAuthUrl();
In callback page:
require_once __DIR__.'/social-api/google/Google_Client.php';
require_once __DIR__.'/social-api/google/contrib/Google_PlusService.php';
$this->sn_obj = new Google_Client($google_app_id, $google_secret_key, $call_back_url);
$this->plus_obj = new Google_PlusService($this->sn_obj);
$this->sn_obj->setRedirectUri($call_back_url);
$this->sn_obj->setState($redirect_url);
$requestVisibleActions = array('http://schemas.google.com/AddActivity','http://schemas.google.com/ReviewActivity');
$this->sn_obj->setRequestVisibleActions($requestVisibleActions);
$this->sn_obj->setAccessType('offline');
$this->sn_obj->setScopes(array('https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/plus.login'));
$this->sn_obj->authenticate();
$google_auth_token = $this->sn_obj->getAccessToken();
$google_user_info = $this->plus_obj->people->get('me');
Friends listing page:
require_once __DIR__.'/social-api/google/Google_Client.php';
require_once __DIR__.'/social-api/google/contrib/Google_PlusService.php';
$this->sn_obj = new Google_Client($google_app_id, $google_secret_key, $call_back_url);
$this->plus_obj = new Google_PlusService($this->sn_obj);
$this->sn_obj->setRedirectUri($call_back_uri);
$this->sn_obj->authenticate();
$user_info = $this->plus_obj->people->listPeople($token['oauth_uid'],'visible');
In general, when working in offline mode, you need to store the entire object that comes back from the server - not just the auth token. This object includes the long-lived refresh token as well as information about when it needs to do a refresh. Passing this entire token to the service allows it to refresh the token for you.
The answer you came up with looks like you do the refresh yourself manually - which is fine, but shouldn't be necessary in general.
In some cases, if a user authorizes your app before you have requested offline mode, and you later request offline mode, you still won't get the refresh token. Google will only give a refresh token when asked if there is no auth token, current or expired, that was issued. There are two ways around this:
When you switch to using offline mode, invalidate your old client id / secret and start using a new one. or
Have the user de-authorize your app via https://accounts.google.com/b/0/IssuedAuthSubTokens or (if you're using Google+ Sign-In) via https://plus.google.com/apps
Finally managed to get get it done
On Friends listing page:
require_once __DIR__.'/social-api/google/Google_Client.php';
require_once __DIR__.'/social-api/google/contrib/Google_PlusService.php';
$this->sn_obj = new Google_Client($google_app_id, $google_secret_key, $call_back_url);
$this->plus_obj = new Google_PlusService($this->sn_obj);
if(!$this->sn_obj->getAccessToken()){
$this->sn_obj->refreshToken($refresh_token_from_db);
}
$google_auth_token = $this->sn_obj->getAccessToken();
$google_auth_token_arr = json_decode($google_auth_token,true);
$url = 'https://www.googleapis.com/plus/v1/people/'.$uid_from_db.'/people/visible?access_token='.$google_auth_token_arr['access_token'].'&format=json';
$c = curl_init($url);
curl_setopt($c, CURLINFO_HEADER_OUT, 1);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HEADER, 0);
$contents = curl_exec($c);
curl_close($c);
$user_info = json_decode($contents, true);
Related
I used instagram public api (adding __a=1 to parameters of an url) to get a post detail (caption ,imageUrl, postType, likes, comments , viewsCount). But it seems that Instagram banned that recently and returned a 403. It also asks for login when I try to directly open a post by its usrl.
I tried to use the instagram private api (https://mgp25.github.io/) for getting post details, but after some requests instargam banned that too:
"throttled by instagram because of too many api requests"
Do you have any offer for an alternative?
Actually it is not really banned but now redirects with 302 to auth page. It seems like auth is required when Instagram account and query geoIPs are different. Alternative is to use official API. No scraping can be done, because the profile link now also requires authentication. You can do authenticated scraping but you are limited to 200 queries ( that Instagram sends to get data) per hour.
Instagram blocked all public endpoints with some limitations and hit rate. Now you need to send the user's session to get the response.
Did you notice the same endpoint returning the JSON response when you are logged in on Instagram in the same browser? Yes, that because whenever you are hitting the URL like "https://www.instagram.com/anything/?__a=1", your browser sending the live and valid sessionid to Instagram. Since you are logged in hence Instagram served you well.
Ever you wonder why the same endpoint started to work again after changing the Internet connection from Wifi to Mobile hotspot or try with another internet service provider.
It's because your IP got blocked and no more free hot babes for you until you are logged in.
Below is the PHP code to give a try with sessionid.
<?php
// keyword or user name
$hashtag = $username = "msevylynch";
// $endpoint = "explore/tags/$hashtag"; // hashtag search
$endpoint = $username; // user search
// login in insta account and copy session from browser's cookie tab
$sessionid = '<YOU-SESSION-ID-PICK-FROM-BROWSER-AFTER-LOGIN>';
$ch = curl_init();
https://www.instagram.com/explore/tags/msevylynch/?__a=1
curl_setopt($ch, CURLOPT_URL, "https://www.instagram.com/{$endpoint}/?__a=1");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Cookie: ds_user='.$username.'; igfl='.$username .'; sessionid=' . $sessionid,
'User-Agent: Instagram 7.16.0 Android'
));
$response = curl_exec($ch);
header('Content-Type: application/json');
echo $response;
?>
Still no luck then it means Instagram blocked you or your IP for some time due to
hitting endpoint too early or very fast programmatically
denied the presented challenge
seems it's an automated hit
password is changed
you are logged out
or your internet bill is over due .. ha ha ha
Thank you for the reading this long, much apriceated.
Instagram is getting very strict with __a=1 endpoint. Your best bet in 2021 to get Instagram profile info is to use clean residential proxies
They require residential IPs to access ?__a=1 pages without login. https://webscraping.ai works for it if you use proxy=residential parameter. An example of such a request:
curl "https://api.webscraping.ai/html?api_key=test-api-key&proxy=residential&url=https%3A%2F%2Fwww.instagram.com%2Finstagram%2F%3F__a%3D1"
I built and maintain a PHP web application with an existing set of users. Authentication is username password, within the application.
There is now a requirement to provide access to a large new set of users, with existing Azure AD accounts. The client wants these users to be able to login using their Azure identities. The existing users would continue to authenticate the way they currently do.
I assumed this would be similar to Facebook/Google etc. SSO , but I'm struggling to find any examples of this in the Microsoft resources, or any libraries out there that will enable this. Is what I describe a valid use case, and achievable with Azuer AD Authentication?
Approach 1: Basically, to access the resources via Azure AD from PHP web application, you can refer to Web Application to Web API
To integrate Azure AD in PHP web applications, we need to follow authorization code grant flow steps to build several custom HTTP requests. E.G. To get access token via OAuth 2.0 protocol, we should refer to the steps on Authorization Code Grant Flow. generally, we will build 2 HTTP requests to get access token:
Request an authorization code.
Use the Authorization Code to Request an Access Token:
Please check this PHP test project for your reference
Approach 2 :
Please refer this github code:https://github.com/CoasterKaty/PHPAzureADoAuth
Try with these steps
Create app registration Azure AD > App registrations and click New registration.
2)After creating app registration Copy the client ID and tenant ID, pasting them into _OAUTH_SERVER and _OAUTH_CLIENTID in config.inc. The _OAUTH_SERVER entry should be the login.microsoftonline.com URL but with TENANT_ID replaced with your directory (tenant) ID
3)add a new secret and select the appropriate time. Don’t forget you will need to update this before it expires, so make a note in your calendar. Once done, copy the secret value and paste this into _OAUTH_SECRET within config.inc
4)After that able to browse to your application and be prompted to log in.. On your first go, you’ll be asked to allow permissions for everyone on your tenant (assuming you have the appropriate admin rights).
After registering the azure ,You can refer this code for a post request
eg:
<?php
$appid = "xxx";
$tennantid = "xxx";
$secret = "xxx";
$login_url ="https://login.microsoftonline.com/".$tennantid."/oauth2/v2.0/authorize";
session_start ();
$_SESSION['state']=session_id();
echo '<h2><p>You can Log In with Microsoft</p></h2>';
if ($_GET['action'] == 'login'){
$params = array (
'client_id' =>$appid,
'redirect_uri' =>'https://example/',
'response_type' =>'token',
'response_mode' =>'form_post',
'scope' =>'https://graph.microsoft.com/User.Read',
'state' =>$_SESSION['state']);
header ('Location: '.$login_url.'?'.http_build_query ($params));
}
if (array_key_exists ('access_token', $_POST)){
$_SESSION['t'] = $_POST['access_token'];
$t = $_SESSION['t'];
$ch = curl_init ();
curl_setopt ($ch, CURLOPT_HTTPHEADER, array ('Authorization: Bearer '.$t, 'Conent-type: application/json'));
curl_setopt ($ch, CURLOPT_URL, "https://graph.microsoft.com/v1.0/me/");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$rez = json_decode (curl_exec ($ch), 1);
if (array_key_exists ('error', $rez)){
var_dump ($rez['error']);
die();
}
}
I used instagram public api (adding __a=1 to parameters of an url) to get a post detail (caption ,imageUrl, postType, likes, comments , viewsCount). But it seems that Instagram banned that recently and returned a 403. It also asks for login when I try to directly open a post by its usrl.
I tried to use the instagram private api (https://mgp25.github.io/) for getting post details, but after some requests instargam banned that too:
"throttled by instagram because of too many api requests"
Do you have any offer for an alternative?
Actually it is not really banned but now redirects with 302 to auth page. It seems like auth is required when Instagram account and query geoIPs are different. Alternative is to use official API. No scraping can be done, because the profile link now also requires authentication. You can do authenticated scraping but you are limited to 200 queries ( that Instagram sends to get data) per hour.
Instagram blocked all public endpoints with some limitations and hit rate. Now you need to send the user's session to get the response.
Did you notice the same endpoint returning the JSON response when you are logged in on Instagram in the same browser? Yes, that because whenever you are hitting the URL like "https://www.instagram.com/anything/?__a=1", your browser sending the live and valid sessionid to Instagram. Since you are logged in hence Instagram served you well.
Ever you wonder why the same endpoint started to work again after changing the Internet connection from Wifi to Mobile hotspot or try with another internet service provider.
It's because your IP got blocked and no more free hot babes for you until you are logged in.
Below is the PHP code to give a try with sessionid.
<?php
// keyword or user name
$hashtag = $username = "msevylynch";
// $endpoint = "explore/tags/$hashtag"; // hashtag search
$endpoint = $username; // user search
// login in insta account and copy session from browser's cookie tab
$sessionid = '<YOU-SESSION-ID-PICK-FROM-BROWSER-AFTER-LOGIN>';
$ch = curl_init();
https://www.instagram.com/explore/tags/msevylynch/?__a=1
curl_setopt($ch, CURLOPT_URL, "https://www.instagram.com/{$endpoint}/?__a=1");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Cookie: ds_user='.$username.'; igfl='.$username .'; sessionid=' . $sessionid,
'User-Agent: Instagram 7.16.0 Android'
));
$response = curl_exec($ch);
header('Content-Type: application/json');
echo $response;
?>
Still no luck then it means Instagram blocked you or your IP for some time due to
hitting endpoint too early or very fast programmatically
denied the presented challenge
seems it's an automated hit
password is changed
you are logged out
or your internet bill is over due .. ha ha ha
Thank you for the reading this long, much apriceated.
Instagram is getting very strict with __a=1 endpoint. Your best bet in 2021 to get Instagram profile info is to use clean residential proxies
They require residential IPs to access ?__a=1 pages without login. https://webscraping.ai works for it if you use proxy=residential parameter. An example of such a request:
curl "https://api.webscraping.ai/html?api_key=test-api-key&proxy=residential&url=https%3A%2F%2Fwww.instagram.com%2Finstagram%2F%3F__a%3D1"
I've done a lot of searching and I've found outdated tutorials that don't work...
I have a site made with PHP and when I submit a particular form in my admin area, I want to publish to my Facebook "fan page"
There is no RSS available, so do you have any example to directly post to the Facebook fan page (not user wall) using php sdk?
Thank you!
Finally, after a lot of tests, it worked, without the PHP SDK. This is the step by step guide:
1. Get permissions and the page token
Go to https://developers.facebook.com/tools/explorer/ and select your app from the first drop down menu, in the left.
Click on the button "Get access token", and in the "Select Permissions" window, click in "Extended Permissions" and check manage_pages and publish_stream, and click in "Get Access Token" blue button.
You may be asked in this step to grant permissions to your app to access to your Facebook account, accept.
Next, click at the end of the text field next to the "GET" drop down, and replace the numbers for: me/accounts, and click in the blue button next to this text field.
You'll get the tokens for all your pages, including your app page. Find your page name in the list, will look like this: "name": "Your page name"
When you located your page, copy the access token for the page (will be really long), that can look like this: "access_token": "XXXXXXXX". Also copy the id of the page: "id": "XXXXX".
That's all for this step, we can start coding now.
2. Post to your page wall via PHP
First, for this script, you'll need a server supporting curl.
We start the PHP document defining the page access token and the page id that we've get in the 1st step:
<?php
$page_access_token = 'XXXXXXX';
$page_id = 'YYYYYYYY';
After that, we create an array with the info to post to our page wall:
$data['picture'] = "http://www.example.com/image.jpg";
$data['link'] = "http://www.example.com/";
$data['message'] = "Your message";
$data['caption'] = "Caption";
$data['description'] = "Description";
You can of course, use any other post parameter described in https://developers.facebook.com/docs/reference/api/post/ and if you don't need one or many of the parameters above you can simply delete it.
Ok, At this point we add to the array the access token:
$data['access_token'] = $page_access_token;
And we set our post URL, to post in our page:
$post_url = 'https://graph.facebook.com/'.$page_id.'/feed';
And the last step, we'll use a curl to post our message in our page wall:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $post_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($ch);
curl_close($ch);
?>
After that, we can save our PHP document, and try to execute it. The post may appear in our Facebook page.
Hope this code helps to other people with the same problem!
You can test tokens using
Facebook Access Token Debugger
Working solution for API v.2.5
Get code for app_id as parameter of response_uri
https://www.facebook.com/dialog/oauth?client_id=".$app_id."&redirect_uri=".$response_uri."&response_type=code&scope=manage_pages,publish_pages
Get access_token based on code, app_id and app_secret as result of response_uri
https://graph.facebook.com/oauth/access_token?grant_type=authorization_code&client_id=".$app_id."&client_secret=".$app_secret."&code=".$code."&redirect_uri=".$response_uri
Get never expiring page_access_token for page_id based on access_token
https://graph.facebook.com/v2.5/".$page_id."?fields=access_token&access_token=".$access_token
As an addition to nmarti answer. Valid for API v.2.4.
If you don't want to go Facebook API console, rather do API calls, there are some instructions.
First of all, you have to have Facebook user, being admin on the page you want to post, also you have to create Facebook App in order to proceed.
Do login request, to get user token:
https://www.facebook.com/dialog/oauth?client_id=%app-id%&redirect_uri=%your-site-url%&response_type=token&scope=manage_pages,publish_pages
In response, you should get %user-token%, save it, you will need in the next step.
Read More
Ask for long lived token:
https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=%app-id%&client_secret=%app-secret%&fb_exchange_token=%user-token%
Now you will have %long-lived-token%, required to get long lived page token.
Read More
Now, get a list of your Facebook Pages,
https://graph.facebook.com/v2.4/%page-admin-user-id%/accounts/?access_token=%long-lived-token%
Find in the list your Page, and a page token, now you can continue with posting to page using nmarti example.
Also Facebook says:
The resulting page access token will not have any expiry time.
Read More
Here is the resource you are looking for. Scroll down to Page Login and read from there.
You have to get an access token for your page and then use that token when posting. This is assuming that you want your post to appear "from the page". IE - posting as if you were the page.
the actual call to the graph api to create a post object, and how to do it, can be found at this url from the facebook documentation.
I have spent quite some time now trying to establish how, and then the best practise to push some data from my web server to the facebook page created for this purpose.
I have read and understand the process of using access tokens. I have generated an access token for myself, which can be used to post to the page as me ok. I understand this should be used to generate the access token for the page to post as the page which is a ittle more tricky. However, this process involves me logging in and generating an access token which seem inherently bad / inconvenient for an automated process.
For this reason i followed the guides to create an app. I (think I have) linked the app to the page, and thus attempt to push data via the appid and secret from my php code to the page.
When doing this I am presented with this error
{"error":{"message":"(#210) Subject must be a page.","type":"OAuthException","code":210}}
my testing code is this:
$data['picture'] = "http://www.example.com/image.jpg";
$data['link'] = "http://www.example.com/";
$data['message'] = "Your message";
$data['caption'] = "Caption";
$data['description'] = "Description";
$data['access_token'] = $app_token2;
$post_url = 'https://graph.facebook.com/'.$app_id.'/feed';
$url1 = "https://graph.facebook.com/endpoint?key=value&access_token=".$app_id."|". $app_secret ;
echo "<br>$post_url";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $post_url);
//curl_setopt($ch, CURLOPT_URL, $url1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($ch);
curl_close($ch);
echo "$return";
I appreciate using the app for server initiated posting using a permanent (ish) secret is the correct way, but I have found very little documentation on how this process is achieved, hence this question.
Your $post_url is pointing to your $app_id variable, the message says it should point to a page, try getting the id of your page from the /me/accounts endpoint of the graph and putting that in there instead. Though I suspect you will need to use a page access_token (also from the /me/accounts endpoint ) to post to your page
Right, I have worked on this for quite some time and found several errors in my code, but have not answered the question fully.
For starters, you do not post to the appid as mentioned above - its just wrong. The code for posting to userid/feed works when using an access token generated from appid + secret using
$url2 = "https://graph.facebook.com/oauth/access_token?client_id=".$app_id."&client_secret=". $app_secret."&grant_type=client_credentials";
this app access token is valid for as long as your app secret is. Also, if I generate a temporary access code for ME via the graph explorer, parse me/accounts manually and use the page token in
$post_url = 'https://graph.facebook.com/'.$page_id.'/feed';
It posts correctlly as the page.
Secondly, all server side call are required to have appsecret_spoof in them which is generated from
$appsecret_proof= hash_hmac('sha256', $app_token2, $app_secret);
now, according to the facebook docs, a http get call to my userid/accounts should yield page access tokens for all pages the user administers (and also presumably the app).
This can also be called directly by using
$url3 = "https://graph.facebook.com/".$page_id."?fields=access_token";
so when a get is made to this address (including app access token & appsecret_spoof) all i get is 'True' ??
Likewise, when the correct call to
$rob1 = "https://graph.facebook.com/".$user_id."/accounts";
I receive an error
{"error":{"message":"(#10) Application does not have permission for this action","type":"OAuthException","code":10}}
OK permission issue then ! Well the documentation says that only manage_pages is required to retrieve the page token from page_id/accounts, so I trawl through lots of pages and find you can do this by calling this url
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=read_stream
This throws up via facebook gui an accept / deny page for each scope (i ended up adding manage_pages, publish_stream & read_stream to my app) none of which seem to solve the problem !
Right sorted !! FWIW the code above functions correctly, however the way it is setup on facebook leaves a lot to be desired !!!
I began messing with my app and changed its name, type (was an app linked to the page - now isnt) removed perms and also changed the domain name (removed) and all site url details (also removed). this prompted a different error msg which stated the domains did not match. So, I readded just the app domain & site url, saved and all of a sudden my failed code started working !
Having tidied my code up a little I can now see the page access token just fine as I expected. I just wish the facebook guides would cross reference this setup as it is not at all obvious !!!
my working code ended up as thus ($perm_url is used as one time link to allow perms via gui)
$perm_url = "https://www.facebook.com/dialog/oauth?client_id=".$appid."&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=publish_stream,manage_pages,read_stream,status_update";
echo "<br>Test";
$facebook = new Facebook(array('appId' => $appid , 'secret' => $appsecret ,));
$access_token = $facebook->getAccessToken();
$pageinfo = $facebook->api("/".$page_id."?fields=access_token");
$page_access_token = $pageinfo['access_token'];
echo "<br>Holy Grail = $page_access_token ";