Skip to content

Instantly share code, notes, and snippets.

@mTorres
Last active January 29, 2016 16:00
Show Gist options
  • Save mTorres/b4808841bf718abcb940 to your computer and use it in GitHub Desktop.
Save mTorres/b4808841bf718abcb940 to your computer and use it in GitHub Desktop.
<?php
/**
* Before trying this you must need to [create](https://console.developers.google.com/):
* - Google API Secred ID
* - Client secret
* - Also configure the callback point in the console to be this same script
* ([more info](https://developers.google.com/api-client-library/php/start/get_started)
*
* Edit the createGClient function accordingly
*
* Also you need to install Symfony HttpFoundation, Monolog and, of course, Google PHP Api Client:
*
* $ composer require "symfony/http-foundation:^2.8" monolog/monolog "google/apiclient:~2.0@dev"
*
* (NOTICE: At the time of this writing there's no stable version for Google PHP API client)
*
*/
// Adapt this path to your composer's autoload file
require __DIR__ . "/../vendor/autoload.php";
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$request = Request::createFromGlobals();
function renderLogin() {
return <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Google OpenID connect test</title>
</head>
<body>
<h1>Google Oauth test</h1>
<p>
Click <a href="/index.php?oauth-start">here</a> to start the thing
</p>
</body>
</html>
HTML
;
}
function renderUserInfo($userinfo) {
return <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Google OpenID connect test</title>
</head>
<body>
<h1>Google Oauth test</h1>
<p>
Ok, so you are {$userinfo["name"]} and your mail is {$userinfo["email"]}
</p>
</body>
</html>
HTML
;
}
function renderError(Exception $e) {
return <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ERROR - Google OpenID connect test</title>
</head>
<body>
<h1>Google Oauth test</h1>
<h4>An error occured!</h4>
<ul>
<li>File: {$e->getFile()}</li>
<li>Line: {$e->getLine()}</li>
</ul>
<p>
{$e->getMessage()}
</p>
</body>
</html>
HTML
;
}
function createGClient() {
$gclient = new Google_Client([
"client_id" => "MY_CLIENT_ID",
"client_secret" => "MY_CLIENT_SECRET",
"redirect_uri" => "http://www.example.com/index.php"
//"hd" => "mydomain.com"
]);
$gclient->addScope('profile email');
$log = new Logger('name');
$log->pushHandler(new StreamHandler('gapi_php_client.log', Logger::DEBUG));
$gclient->setLogger($log);
return $gclient;
}
function createGPlus($gclient) {
return new Google_Service_Plus($gclient);
}
try {
if ($request->query->has('code') || $request->query->has('error')) {
// HANDLE Google OAuth callback
if (null !== $error = $request->query->get('error', null)) {
$this->logger->debug("Google sends an error: $error");
if ($error == "access_denied") {
throw new Exception("User did not give permission!");
}
throw new Exception("Google Login error: $error");
}
$code = $request->query->get('code');
if (!empty($_SESSION['state'])) {
//OAuth authentication attempt with state token
$state = $_SESSION['state'];
if ("" == $returned_state = $request->query->get('state', "")) {
throw new Exception("Google OAuth Request does not have a [state] parameter!");
}
if ($state != $returned_state) {
throw new Exception("Invalid state parameter in Google OAuth Request does not match with stored state");
}
}
$gclient = createGClient();
$plus = createGPlus($gclient);
$googleToken = $gclient->fetchAccessTokenWithAuthCode($code);
if (array_key_exists("error", $googleToken)) {
throw new Exception($googleToken["error"] . ": " . $googleToken["error_description"]);
}
try {
$person = $plus->people->get("me");
}
catch(Exception $e) {
$error = json_decode($e->getMessage(), true));
throw new Exception($error["error"]["message"]);
}
$userinfo = ["name" => $person->getDisplayName(), "email" => $person->getEmails()[0]->getValue()];
$response = new Response(renderUserInfo($userinfo));
}
elseif ($request->query->has('oauth-start')) {
// User requested to start the OpenID Connect flow, so redirect to Google Server
// TODO: Create a state random string and put it into the SESSION and into the request parameters to check
// at callback
$gclient = createGClient();
$response = new RedirectResponse($gclient->createAuthUrl());
}
else {
// Just render info page with link to start the OpenID Connect flow
$response = new Response(renderLogin());
}
}
catch(Exception $e) {
$response = new Response(renderError($e), 400); // This can be a 500 also but, you know...
}
$response->prepare($request);
$response->send();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment