Перейти к основному содержимому

Авторизация в Google с OAuth 1.0

· 3 мин. чтения

Google как и Твиттер, предоставляет разработчикам возможность использовать OAuth 1.0 для авторизации пользователя стороннему приложению предоставлению конкретных данных по API, причём поскольку Google не централизованный Facebook и у него много полноценных сервисов типа Youtube и Picasa, то для каждого из них выборка данных своя. В общем эта авторизация (ключевые слова - OpenID, AuthSub, Federated Login) и доступ к данным (ключевые слова - JSON, XML, REST, Atom) называется Google Data Protocol.

Используем Zend Framework

OAuth библиотек много - есть поставляемая для твиттера библиотека, есть поставляемая для гугла.. но я воспользуюсь Zend - платформой.

1. Регистрируем домен = приложение, запоминаем Consumer Key + Secret. На локальной машине не получится - надо полноценно работающий домен

  1. Ставим из Zend Framework два модуля - Crypt и Oauth.

  2. Создаём настройки где указываем пути к услугам авторизации

$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;

  1. Теперь проверяем есть ли у нас ключ доступа (access token) - на самом деле этот этап в самом конце происходит, но в коде он стоит именно тут. Ключ доступа мы получаем либо обменом на ключ запроса (request token), либо из сессии/БД куда его сохранили после первого получения. Метод getAccessToken возвращает полноценный объект, поэтому мы сериализуем его
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));
}
  1. Основная часть - если ключа доступа нет - запрашиваем ключ запроса с указанными двумя услугами (scope). Первый даст доступ к контактам а второй - к почте. Если же клиент уже подтвердил запрос и ключ доступа мы имеем (или получили из сессии/БД), то делаем два http-запроса.
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']
);
}

В помощь существует OAuth playground. Если вам нужны другие данные от гугла, то по протоколу достаточно определить другой scope, вот некоторые из них..

Некоторые возможные значения scope-параметра
Analyticshttps://www.google.com/analytics/feeds/
Google Buzzhttps://www.googleapis.com/auth/buzz
Calendarhttps://www.google.com/calendar/feeds/
Contactshttps://www.google.com/m8/feeds/
Documentshttps://docs.google.com/feeds/
GMailhttps://mail.google.com/mail/feed/atom
orkuthttps://orkut.gmodules.com/social/rest
Picasa Webhttps://picasaweb.google.com/data/

Единственная огромная проблема всего этого решения — повторный запрос на привилегии когда пользователь уже авторизовал доступ. В твиттере это решалось использование authenticate URL, в фейсбуке в принципе нет такой проблемы.. с гуглом же пока есть гибридное решение с OpenID где я сейчас и копаюсь.