Eitan
Eitan

Reputation: 1386

GOOGLE id - PHP use

I am trying using Google-ID by PHP code.

Some clarifications:

I looked at the sample on https://developers.google.com/+/web/signin/server-side-flow

I don't understand the example on steps 2+7 (is it twig? I don't know twig, and don't have one).

Step 6 - I have valid value for : authResult['code'], but cannot call plus.php (is it the plus.php at library: https://code.google.com/p/google-api-php-client/?

If so - it is not compiled run as well (it is looking for Google_Client class, which is not found - Seems a bug on Google, since I need to copy all the classes where is plus.php.

Thanks :)

Upvotes: 0

Views: 1171

Answers (1)

Eitan
Eitan

Reputation: 1386

Since I have solved the problem by myself, I would like to contribute my solution.

The Google+ documents are not explained properly, and there are some bugs I had to deal with.

You can look at: https://developers.google.com/+/web/signin/add-button and on: https://developers.google.com/+/web/signin/server-side-flow.

For google server side:

Create a project and reference on google server side (Finally, you shall have "Compute Engine and App Engine", "Client ID for web application", "Key for server applications").

1. Go to : https://console.developers.google.com/project Project +
create project. Named the project+id.

2.  Add google+ API. APIS & AUT -> APIS. Add Google+ (Enable it).
3. Go to APIS & AUT -> Credentials. Create new client ID (For Web application). Authorized JavaScript – enter the site name (maybe
several lines). Authorized redirect URI – Clear it. Attention:
Client id + Client secret are declared.
4. Go to APIS & AUT -> Credentials. Create a new key, Choose server key, and press "Create".

For you php side:

  1. Download php api libray from: https://code.google.com/p/google-api-php-client/

  2. The Client.php file shall be in Google folder, because of little bug, that you cannot include it in your script, unless you do a little trick, as explained later - so change the folder whether necessary, and put the whole folder on your site (only this folder and sub folders). The fix may look like this:

    set_include_path(get_include_path() . PATH_SEPARATOR . DIR );

  3. You shall keep in $_SESSION variables the values of the token, and email (of user that login). That can be checked later like $_SESSION["TOKEN"] = $_POST["TOKEN"] for forgery.

  4. For retrieving the user email, you shall have to add scope, as the following code:

    $google_client->addScope(Google_Service_Oauth2::USERINFO_PROFILE);
    $google_client->addScope(Google_Service_Oauth2::USERINFO_EMAIL);
    

    /* ... */

    $me = $plus->people->get("me");
    $email = $me['emails'][0]['value'];
    

As you see, $me is the magic that retrieve the current user. 5. On client side, you have to use only one button (even for signing in and logged in). Use same form for login and sign in, and swap it, by some jquery command like html().

  1. You will have to use google api and make a button, with callback reference.

Here is the php code:

<?php
# REQUIRED MODULES:
/*.
    require_module 'standard';
    require_module 'mysqli';
    require_module 'spl';
    require_module 'simplexml';
    require_module 'dom';
    require_module 'session';
.*/
require_once __DIR__ . "/stdlib/all.php";
require_once __DIR__ . '/Google/Client.php';
require_once __DIR__ . '/Google/Service/Plus.php';

/*. string .*/ $aut_code = "";
session_start();

    try {
        $aut_code = $_POST["code"];
        set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ ); /* the fix for using the 'google' library, unless it will not run properly */
        $id = "<Client-id from 'Compute Engine and App Engine'";
        $google_client = new Google_Client();

        $google_client->setApplicationName("your application name created in google side");
        $google_client->setClientId("Client-id of 'Client ID for web application'");
        $google_client->setClientSecret("Client secret of 'Client ID for web application'");
        $google_client->setRedirectUri("postmessage"); /* alway postmessage. */
        $google_client->setDeveloperKey("Api key of 'Key for server applications'");

        $google_client->addScope(Google_Service_Oauth2::USERINFO_PROFILE); /* important for getting access to user profile */
        $google_client->addScope(Google_Service_Oauth2::USERINFO_EMAIL);/* important for getting access to user email */

        $google_client->setAccessType("offline");
        $google_client->authenticate($aut_code);
        $access_token = $google_client->getAccessToken();
        $plus = new Google_Service_Plus($google_client);
        $_SESSION['access_token'] = $access_token;
        $me = $plus->people->get("me"); /* me is the current logged in user */
        $email = $me['emails'][0]['value'];
        $_SESSION["EMAIL"] = $email; /* keep in session variable whatever you send to client */
        $_SESSION["GOOGLELOGIN"] = 1; /* keep in session variable whatever you send to client */
        echo "ok," . urlencode($access_token) . "\n" . $email; /* response from server */
    } catch(Exception $e) {
        echo "error:" . $e->getMessage();
    }
?>

The part of html is split to two:

In body section, you shall add a button:

<div id="id_googleSignInDlg">
    <table>
        <tr>
            <td id="id_googlelogDesc">
            Google log in:
            </td>
            <td id="id_googlelogButton">
              <span class="g-signin"
                data-scope="https://www.googleapis.com/auth/userinfo.email"
                data-clientid="Client ID for web application"
                data-redirecturi="postmessage"
                data-accesstype="offline"
                data-cookiepolicy="single_host_origin"
                data-callback="googleSignInCallbackLog"
                data-approvalprompt="force"
                data-height="short"
                >
              </span>
            </td>
        </tr>
    </table>
    <div id="id_logreg"></div>
</div>

and for reference to google.

   <script>
    (function () {
      var po = document.createElement('script');
      po.type = 'text/javascript';
      po.async = true;
      po.src = 'https://plus.google.com/js/client:plusone.js?onload=start';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(po, s);
    })();
    </script>

don't forget to include:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">

in Javascript, do:

    function googleSignInCallbackLog(authResult) {
    'use strict';
    var s,
        temps,
        values;
    $("#id_googleSignInDlg").dialog("close");
    if (authResult.code) {
        $.ajax({
            url: 'googleOpenIdLogin.php',
            type: 'POST',
            dataType: "html",
            success: function (result) {
                s = result;
                if (s.substring(0, 3) === 'ok,') {
                    temps = s.substring(3, 4000);
                    values = temps.split("\n");
                    googleToken = decodeURIComponent(values[0]);
                    newAccountOn = false;
// check login.
                } else {
                    // error !!!
                }
            },
            data: {
                'code': authResult.code
            }
        });
    } else if (authResult.error) {
        $("#id_googleSignIn").dialog("close");
    }
}

id_googleSignInDlg is the dialog that includes dynamically the html part of the google+ button.

And finally, when using one dialog for two abilities (sign in and login), you shall have code like this:

function loginclick() {
    'use strict';
    if ($("#id_regdialog").html() === "") {
        $("#id_regdialog").html($("#id_logreg").html());
    }
    if ($("#id_logindialog").html() !== "") {
        $("#id_logreg").html($("#id_logindialog").html());
    }
    $("#id_logindialog").html("");
...
    $("#id_googlelogButton").css("opacity", 1);
...
}

and because the google button is shown for less than second on the screen - may be annoying, you can have on css file the following style:

-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
opacity: 0;

Hope this post will be helpful.

Upvotes: 1

Related Questions