Facebook federated login

Is there a way to implement the Facebook login into the federated login plugin? I have to do it but I have no idea how to do this. I think Facebook is today the most social login used, so it should be added among Google, OpenID, Yahoo and others.
Thanks

Comments

  • acrylian Administrator, Developer
    Possible is nearly everything. The reason it is not in there is that both the developer of it and I don't have FB accounts (the FB page is run by a non developing team member for us).
  • Last time we looked Facebook did not provide an open-id login interface. Maybe that has changed. If so adding Facebook would be simple. If there needs to be some sort of API and a handler for federated logon would need to be written to that API.
  • I searched a bit and found that Facebook uses OAuth 2.0 for login, so federated plugin cannot be used. Its social plugin, using JS SDK, seems to simplify the work, but I haven't understood well how it works.
    I think it passes to the desired page (for example register.php) an array with the user information, userid, email, name and a token (a useful how-to can be found here http://tinyurl.com/ch7z2n7 ).
    Now, how can I handle this data to interface with ZP? Should I create a new page (plugin?) to simply send this data to the ZP registration system or should I use the object model from scratch?
  • acrylian Administrator, Developer
    You should maybe take a look at the Twitter plugin which if I recall right also uses OAuth. Probably you can adapt it to do the same or similar for FB.

    To your last question you will need the object model in any case anyway. For example to get the current logged in admin users so you know which one to log in with. Since ZP can have multiple admins.
  • uhm, I looked to the twitter plugin and it uses OAuth, but it seems a quite complex way to proceed for me.
    I will try to use the Javascript SDK provided by facebook and call directly the register_user plugin as the register form do, following the tutorial I posted in my last reply.
    Probably the author of twitter plugin will be able to adapt it in some minute and it will be appreciated by lots of users, but I have no idea how it works, it's a too long and complex code for me.
  • The twitter plugin uses OAuth to log into facebook. What you want is sort of the reverse--if someone is logged into facebook then you want to grant him Zenphoto authorization.

    If OAuth has the ability to query facebook for the currently logged in user then you would want to build a federated login "handler" that would deal with that.

    The following is a simple script for logging into Zenphoto "from the outside".

    `
    <?php
    /*
    * Demo script for co-ordinating zenphoto credentials with some outside agency.
    *
    */

    define('OFFSET_PATH', 3);
    require_once(dirname(dirname(dirname(__FILE__))).'/zp-core/admin-functions.php');
    if (isset($_GET['redirect'])) {
    $redirect = sanitize($_GET['redirect']);
    } else {
    $redirect = '';
    }
    if (isset($_GET['user'])) {
    $user = sanitize($_GET['user']);
    } else if(isset($_GET['requestor'])) {
    $user = sanitize($_GET['requestor']);
    } else {
    $user = '';
    }
    if (isset($_GET['email'])) {
    $email = sanitize($_GET['email']);
    } else {
    $email = '';
    }

    $mypath = str_replace(SERVERPATH.'/', WEBPATH, str_replace('\\', '/', __FILE__));
    $more = '';
    if (isset($_GET['action'])) {
    switch ($_GET['action']) {
    case 'login':
    if (empty($user)) {
    if (empty($email)) {
    $more = gettext('You must supply a user name or an e-mail address.');
    break;
    } else {
    $user = $email;
    }
    }
    if (Zenphoto_Authority::checkCookieCredentials()) {
    if ($_zp_current_admin_obj->getUser() == $user) {
    $more = sprintf(gettext('%s is already logged in.'),$user);
    break;
    } else {
    $more = gettext('Someone else is logged in.');
    break;
    }
    }
    $more = federated_logon::credentials($user, $email, NULL, $redirect);
    break;
    }

    }
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


    <?php echo gettext('Refered credentials proof of concept'); ?>


    .warningbox {
    padding: 20px;
    background-color: #FFFF00;
    border-top: 1px solid #996600;
    border-left: 1px solid #996600;
    border-right: 1px solid #996600;
    border-bottom: 5px solid #996600;
    margin-bottom: 10px;
    font-size: 100%;
    }
    #main {
    width: 30em;
    }


    function submitUser(action) {
    var user = document.getElementById('user').value;
    var email = document.getElementById('email').value;
    var parms = '<?php echo $mypath; ?>?'+action+'&user='+user+'&email='+email;

    <?php
    if ($redirect) {
    ?>
    parms = parms+'&redirect=<?php echo $redirect; ?>';
    <?php
    }
    ?>
    window.location = parms;
    }








    <?php echo gettext("Federated logon proof of concept."); ?>

    <?php echo gettext('<strong>WARNING: this demonstration is NOT secure. You should not leave this script on any public Zenphoto installation.'); ?>



    user: " />
    e-mail: " />



    <?php
    if (isset($_GET['action'])) {
    switch ($_GET['action']) {
    case 'login':
    if ($more) {
    printf(gettext('Not logged in.'),$user).' ';
    echo $more;
    } else {
    printf(gettext('%s was successfully logged in'),$user);
    }
    break;
    default:
    printf(gettext('%s is an invalid action.'),$action);
    break;
    }

    }
    ?>





    `
    Of course it does no real authentication, but you can see how to get the user logged into Zenphoto once you have accomplished the external authentication.

    The various other OpenID handlers might give you some idea of how to handle the other details.
  • acrylian Administrator, Developer
    The twitter plugin uses OAuth to log into facebook.
    Into Twitter of course..;-)
  • Thanks Stephan, I studied your script and understood that its core is the static function federated_logon::credentials.
    Using the facebook php sdk I solved the fb auth part, so I finally have an array with user data; my idea was passing this data to the federated logon:
    `if (fb user logged in) federated_logon::credentials('fb:'.$user_profile['id'], NULL, $user_profile['name'], $redirect);`
    I made this a plugin; it partially worked, but even if it create the user and log in (if I go to /admin on top I can see "fb:xxxxxxxxx" as the username), the `$_zp_current_admin_obj` object is NULL so other functions that use this object don't recognize the user as logged in.
    Is this a normal behaviour using federated_logon::credentials? How can I fix this?
    I load this function calling it in the plugin with `zp_register_filter('theme_head', 'FBloginHeader');`, is this correct?
    Thanks
  • Two things:

    First, federated_logon::credentials returns a result that may be an error message, so you should be sure that you are not getting some kind of logon error.

    Second, Logon needs to happen sooner than the theme head. If you are not going to make this a federated login handler then you will have to attach to the `load_theme_script` filter. Even this may not work, so the best approach is to make the FB logon a federated logon handler.
  • You're right! Attaching it to the load_theme_script worked.
    This is the simple way to obtain the login:
    `
    //including facebook php sdk
    require_once ('...../facebook.php');
    //Creating our application instance
    $facebook = new Facebook(array(
    'appId' => $appid,
    'secret' => $secretappid
    ));
    //Get User ID
    $FBuser = $facebook->getUser();
    if ($FBuser) if (!$_zp_current_admin_obj){
    try {
    // Proceed knowing you have a logged in user who's authenticated.
    $user_profile = $facebook->api('/me');
    federated_logon::credentials('fb:'.$user_profile['id'], NULL, $user_profile['name'], $redirect);
    } catch (FacebookApiException $e) {
    error_log($e);
    $FBuser = null;
    echo $e;
    }
    }
    `
    Caling the login/logout link with
    `
    if ($FBuser) {
    echo "getLogoutUrl($params = array('next' => $redirect))."\">Logout from FB";
    } elseif (!zp_loggedin()) {
    echo "getLoginUrl($params = array('redirect_uri' => $redirect))."\">Login with FB";
    }
    `
    However it has some issues for the logout, so it would be a cleaner way making a federated logon handler. Have you got some documentation for the federated logon or at least some tips to give me to understand the mechanism and to integrate this handler? I found this plugin very complex to read...
    Thanks
  • What are the issues with logout? Really the only difference between what you have done and what would happen with a federated_logon handler is that would be executed only during a logon request. (But of course that may be the issue--pretty hard to log out if the page refresh logs you back in!)

    Anyway, the above script is the best example of a simplified federated_logon handler. Also, the individual handlers supplied are not so complicated if you ignore the `OpenID_try_auth.php` script. What that does is handle the communication for authentication. Your code replaces that. Google and Yahoo handle the whole transaction "off line" to Zenphoto, so there is no code other than making the connection. Verisign on the other hand only provides a "verification" so the handler has to show the verification result and allow for a redirect back to Zenphoto. What you need to do depends on how Facebook behaves.

    It would appear that the difference in what you have already done and what is needed would be to handle the case where the user was not currently logged in to Facebook.
  • The issues with logout was of course that the page re-login me in on a page refresh after a logout, as you said, but I was aware of it, what I wrote was only a simple try to check if it worked.
    During these days I will try to adapt it following your advices and let you know.
    Thanks again!
  • Nice to see someone working on this and that it's got some progress, good work BigLouis87!
  • Hi. There are news for this "project" or implementation?

    Thanks!
  • acrylian Administrator, Developer
    If there were you would find it on our extensions section. So in short, no.
  • I am actually working on one and will add it to zenFBSuite :)
  • acrylian Administrator, Developer
    Good to hear...;-)
Sign In or Register to comment.