Google, just like Twitter, allows developers to use OAuth 1.0 to authenticate and authorize data use for our application , providing defined data using API, and since Google is not as centralized as Facebook is, it has lots of independent services like Youtube and Picasa, meaning that each one has its own data structure. In general this authorization (keywords here - OpenID, AuthSub, Federated Login) and data access (JSON, XML, REST, Atom) are implemented as Google Data Protocol.
Lets use Zend Framework
There are lots of OAuth libraries - there is one for twitter, there is one provided by Google.. but I'll use Zend framework.1. First, we register our domain = web application, and write down Consumer Key + Secret. We can't really test it on localhost - only externally accessible domain
2. Set up two modules from Zend Framework - Crypt and Oauth.
3. Create settings where we set URLs to auth services
$aGoogleConfig = array(
'callbackUrl' => 'http://kurapov.name',
'siteUrl' => 'https://www.google.com/accounts/',
'authorizeUrl' => 'https://www.google.com/accounts/OAuthAuthorizeToken',
'requestTokenUrl' => 'https://www.google.com/accounts/OAuthGetRequestToken',
'accessTokenUrl' => 'https://www.google.com/accounts/OAuthGetAccessToken',
'consumerKey' => 'kurapov.name',
'consumerSecret' => 'netetonenastojashijsekreteokfpwoekrf'
);
$consumer = new Zend_Oauth_Consumer($aGoogleConfig);
$token = null;
4. Now we check if we have access token - by default it will fail, but it should be first thing to do. We get access key either by request token exchange, or from session/database where it was saved previously. Method getAccessToken returns fully fledged object, so we serialize it
if($_SESSION['GOOGLE_ACCESS_TOKEN']){
$token = unserialize($_SESSION['GOOGLE_ACCESS_TOKEN']);
}
else
if(isset($_GET['oauth_token'])){
$token = $consumer->getAccessToken( $_GET, unserialize($_SESSION['GOOGLE_REQUEST_TOKEN']) );
$_SESSION['GOOGLE_ACCESS_TOKEN'] = serialize($token));
}
5. Main part - if we don't have any key yet, get request token with two defined services (scope). First one gives us access to google contacts, and the second one to email address. If client has already confirmed request and we have access token, then we do two http-requests.
if(!$token){
$token = $consumer->getRequestToken(array( 'scope' => 'http://www-opensocial.googleusercontent.com/api/people/ https://www.googleapis.com/auth/userinfo#email'));
$_SESSION['GOOGLE_REQUEST_TOKEN'] = serialize($token));
$consumer->redirect();
}
else{
$client = $token->getHttpClient($aGoogleConfig);
$client->setUri('https://www-opensocial.googleusercontent.com/api/people/@me/@self');
$client->setMethod(Zend_Http_Client::GET);
$response = $client->request();
$data = Zend_Json::decode($response->getBody());
$client = $token->getHttpClient($aGoogleConfig);
$client->setUri('https://www.googleapis.com/userinfo/email');
$client->setMethod(Zend_Http_Client::GET);
$response = $client->request();
$emailData=explode('&',$response->getBody());
if($emailData){
foreach($emailDataas $sRow){
$aRow=explode('=',$sRow);
$data[$aRow[0]]=$aRow[1];
}
}
$arrProfile=array(
'identifier' => $data['entry']['profileUrl'],
'access_token' => serialize($token),
'verifiedEmail' => $data['email'],
'name' => $data['entry']['name'],
'photo' => $data['entry']['thumbnailUrl'],
'url' => $data['entry']['profileUrl']
);
}
To help out, there is OAuth playground. If you need other google data, then based on protocol scope tou can defined which one, here are some of them..
Possible values of scope-param
| Analytics | https://www.google.com/analytics/feeds/ |
| Google Buzz | https://www.googleapis.com/auth/buzz |
| Calendar | https://www.google.com/calendar/feeds/ |
| Contacts | https://www.google.com/m8/feeds/ |
| Documents | https://docs.google.com/feeds/ |
| GMail | https://mail.google.com/mail/feed/atom |
| orkut | https://orkut.gmodules.com/social/rest |
| Picasa Web | https://picasaweb.google.com/data/ |
The only problem with this entire solution — repeatable privilege request even if user has confirmed it previously. Twitter solved it by using authenticate URL, facebook doesn't have it at all.. and with google.. well there is a hybrid solution with OpenID that I'm investigating right now.