I am working on FB application using the PHP SDK.
The implementation seems to be correct and everything seems fine.
The problem I am facing is that some users profiles do not contain an email address. That is wierd because the application asks for this permissions specifically.
Code for this action:
// 1. If we cant get the user, log him in and request permissions if he has deleted/deauthorized or new to app
if (!$fbCurrentUserID){
$loginUrl = $facebook->getLoginUrl(array(
'scope' => 'email,user_birthday',
));
$this->abortToUrl($loginUrl);
}
try {
$user_profile = $facebook->api('/me');
if (!is_array($user_profile) || empty($user_profile['email'])) {
if ($log = $this->getLog()) {
$log->log('Facebook login no valid userprofile', Zend_Log::ALERT, array('user_profile' => $user_profile));
}
$this->abortToUrl($landingPage_url);
}
// 2.a User has provided data go on...
} catch (FacebookApiException $e) {
// 2.b Something bad happened. Worst case scenario so go to start
if ($log = $this->getLog()) {
$log->log($e->getMessage(), Zend_Log::CRIT);
}
// If he declined or anything went wrong go to LP
$this->abortToUrl($landingPage_url);
}
So I get quite a few logs with the user array not containing the email address field.
Am I missing something? I cannot reproduce this with test accounts or my account when I set email to be visible only to me.
Not every user has an email address set with FB, since you can also register using your mobile.
Related
I am building a web application with OAUTH authentication to Azure AD.
What I mean is, you log into my application via your Azure AD / Office365 account.
After login is succeeded, I match the GUID of the Azure AD user with the user in my Mysql database.
I set in the session information that the user is logged.
I used this howto for the basics of it:
https://kvaes.wordpress.com/2016/10/21/azure-using-php-to-go-all-oauth2-on-the-management-api/
The basics of the code I use for logging a user to my PHP application:
//User is not logged in, try to log in
$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
'clientId' => getsetting('aadsso_clientid'),
'clientSecret' => getsetting('aadsso_secret'),
'redirectUri' => getsetting('aadsso_redirecturl')
]);
if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
$_SESSION['oauth2state'] = $provider->getState();
header('Location: '.$authUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
try {
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code'],
'resource' => 'https://graph.windows.net',
]);
} catch (Exception $e) {
exit ("Connection error. Contact the administrator");
}
// Optional: Now you have a token you can look up a users profile data
try {
// We got an access token, let's now get the user's details (AAD login succeeded)
$me = $provider->get("me", $token);
//Some code here LEFT OUT, to find the user in my MySQL database.
$_SESSION['loggedin'] = 1;
$_SESSION['aadguid'] = $me['objectId'];
} catch (Exception $e) {
// Failed to get user details
exit ("Connection error. Contact the administrator");
}
}
That works fine! But, when I set "$_SESSION['loggedin'] = 1;", the user is logged in to the application.
I really want to understand how to make the user log out of my application, when he logs out of his Azure AD/Office365 session. For example, he logs in to my app, goes to outlook.office.com, clicks logout there. When he goes back to my app and tries to load a page, my app should "see" he's logged out of Azure AD.
How to accomplish this, without losing to much performance of my app?
I am quite a rookie in this, but please give me some tips.
This might not be the same code you are using but Microsoft has a sample on PHP how to auth: https://learn.microsoft.com/en-ca/graph/tutorials/php?tutorial-step=3
you will see that somewhere in that example, they implement a signout URL routing for Laravel.
Then in your app registration under Authentication -> there is a section called Logout URL, if you specify a URL there, then if the user logs off of Azure SSO, it will send a call to that logout URL, to potentially execute the logout URL that you implemented. This will kill the token in your app, which should then now no longer have a session?
I know it's not exactly what you're asking in terms of adding it to your code, but please have a look at the example, you may want to test that out.
I'm developing a Facebook app and downloaded facebook-php-sdk-master file from facebook. It is working great it is just i need the email address of the people who use our app.. and it does not return the email address... i made some research and a youtube video said to request it on getLoginUrl
if ($user) {
$logoutUrl = $facebook->getLogoutUrl();
} else {
$statusUrl = $facebook->getLoginStatusUrl();
$loginUrl = $facebook->getLoginUrl(array('email'=>'email'));
}
but still doest return the email address. Please help. Thanks!
That's not correct. You're requesting the permission to read the user's e-mail address. Any permission requests should be made with the scope field, like so:
$loginUrl = $facebook->getLoginUrl(array(
'scope' => 'email'
));
The above code will create the URL. Now, to direct users to this URL, you can use the following code:
Login
When a user clicks on the above link, they'll be asked to supply the permission for reading their emails.
If you want additional permissions, you can request it the same way. Just add them to the scope field as comma-separated values. The full list of permissions, including defaults, can be found in the Facebook Developers documentation.
I'm trying to activate cookies via the facebook login so it doesnt always depend on the session being there but whenever I set sharedSession to true I get a "The page isn't redirecting properly" error page.. Is this the way I'm suppose to make it so the facebook login uses cookies? I'm using the newest code on github for the facebook SDK (downloaded a freshy today) -> https://github.com/facebook/facebook-php-sdk
I'm not using the javascript SDK. and all of the coding below is fired before any headers are sent out. If I take the sharedSession out, it logs me in correctly, but it doesnt store a cookie with the info needed.
Heres the coding I'm using
$facebook = new Facebook(array(
'appId' => $Sets['facebook']['appId'],
'secret' => $Sets['facebook']['appSecret'],
'sharedSession' => true,
// 'trustForwarded' => true
));
$user = $facebook->getUser();
if($user){
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
// the user is logged into facebook
if($user){
// I register them on my website..
// and then send them to the index page
header('Location: /index.php');
} else {
// they are not registered through facebook
if(isset($_GET['error'])){
// this happens when an error is found
die($_GET['error'].' error');
// header("Location: /login/?error=".urlencode($_GET['error']));
exit;
} else {
// send to facebook to log them in.
$loginUrl = $facebook->getLoginUrl($Sets['facebook']['scope_array']);
// die('sending to '.$loginUrl);
header("Location: ".$loginUrl);
exit;
}
}
You can see I put the die() function before any redirection there, this was for debugging on my end to see if I can figure out where it was failing, but it seems to happen after the user is returned to the website.. I also tried the trustForward => true, but that didnt fix it..
all I'm after is to be able to have the user logged in for a longer period of time, without having to login through facebook everytime they visit the website.
Whats happening is the user is stuck in a loop trying to log into facebook being redirected between facebook and my website because the user is never verified. Again, this ONLY happens when I set 'sharedSession' => true
I'm trying to get the facebook sdk to store a cookie from my website onto the persons computer that tries to login but no cookie is being set.
I get confused by your question. what do you want to achieve:
1) If you want to set store your facebook user_id to cookie, you don't have to do anything. when the oauth process is completed facebook redirect to your "redirect_uri" url, the cookie is set by facebook to a cookie value: fbsr_xxxx (xxxx is your appId)
2) If you want to keep user logged in longer time, you need to set your own session value to determine if the user is logged in or not. in other word, after the facebook oauth flow, your user login status has nothing to do with your facebook session.
BTW: $Users->loginWithOauth, this function has no definition, what's this function for?
the reason is the required permission not granted so eventually it goes to facebook search for the token and comes back.
check for the permission you need.
Hi I have a problem with the Facebook API although I am asking for the permission to get the email I can't get the mail value, what do I do wrong? Here my code:
$facebook = new Facebook(array(
'appId' => 'xxxxxxxx',
'secret' => 'xxxxxxxxxx',
'cookie' => false
));
// See if there is a user from a cookie
$fbuser = $facebook->getUser();
if ($fbuser) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$FBUSER = $facebook->api('/me');
$FBUSER1 = $facebook->api('/me');
print_r($FBUSER1);
} catch (FacebookApiException $e) {
print_r($e);
$USER=false;
}
}
$loginUrl = $facebook->getLoginUrl(array("scope"=>"email, publish_actions"));
A few days ago I was coding a similar login/authorization bit of my app and I had similar results until I properly ordered the flow steps.
From your snippet it looks like you print the $fbuser array before the user actually grants the extended permissions to your app. Let's imagine you were doing some tests with your own account being logged in to facebook: you might have authorized the app once with the basic permission and now it returns these basic data from your account (with no "email" as it belongs to the extended perms).
More code could help to better understand but I would still double check that:
1. the page/popup coming from the FB getLoginURL() method is shown and the user accepts both to login (if not) and to authorize the extended permissions if needed.
2. the return_uri code on your website is ready to catch any data coming from the previous step (eg. print the user details).
Watchout as I see from your code that the return_uri is not defined.
If you send request without access_token, you will get short field set without email and some different fields.
I am having login using facebook functionality in my site. The issue is after getting successful authentication the $facebook->getUser() method returning 0, due to this it's not preceding towards the rest of code. To resolve this issue I modified my APP ID and Secret Key, also I created new APP but still its not working. Also did lot of stuff on google but didn't got any success.
Following is my code :
public function facebookregisterAction() {
require 'auth/src/facebook.php';
$facebook = new Facebook(array('appId' => 'xxxxxxxxxxxxxxx','secret' => 'xxxxxxxxxxxxxxxxxxxxxxx','cookie' => true));
$session = new Zend_Session_Namespace('user');
$user = $facebook->getUser();
if ($session->islogout != 1) {
if ($user) {
try {
$user_profile = $facebook->api('/me');
}catch(Exception $e){}
}
}
Thanks
As a general answer, I found it helpful to start with example.php in the facebook-php-sdk directory.
In my case my test application's URL was different than the site URL. The example.php file provided an error message that was useful enough to diagnose and correct the issue.
It's also a good example of actual usage.
With that said, there's a part that you seem to be missing. The user will have to visit your app's Facebook login URL before the API will be very useful (beyond fetching public information). To find this URL, try:
$url = $facebook->getLoginUrl();
You can give the user a link to click, or quietly redirect the user to this URL if you're requiring a login. A "Hello, World!"-type start would be something like:
if ($user) {
$url = $facebook->getLogoutUrl();
$message = "Click here to log out";
} else {
$url = $facebook->getLoginUrl();
$message = "Click here to log in";
}
print "<a href=$url>$message</a>";
But you'll quickly run into something that is covered by the example.php file: the "access token" (like a session ID) isn't cleared when the user logs out of Facebook. Your application will still see a valid user object, but any API call that hits Facebook will fail.