При написании большинства приложений на платформе Facebook разработчику требуется получить доступ к данным пользователя: список друзей, ньюсфиды, ссылки, likes и т. д. Разумеется, такую информацию нужно передавать, убедившись что она попадет к нужному получателю от определенного отправителя. Для этого FB предлагает использовать разработанную ими схему подписи на базе OAuth 2.0.
Данные о текущем пользователе (или о текущем профиле) FB передает в параметре signed_request, а именно:
$_REQUEST['signed_request'] представляет собой конкатенацию подписи HMAC SHA-256, точки (.) и JSON объекта, упакованного в base64url. Выглядит примерно так (все слитно):
Для того, чтобы FB передавал нашему приложению signed_request, нужно указать это в настройках (т.к. на данный момент это бета фича):

После того, как пользователь разрешит доступ приложения к своим данным, мы будем получать signed_request в каждом запросе к нашему Canvas URL (откуда FB берет контент приложения). Есть несколько способов вызова такого диалога:
Редиректим пользователя на адрес:
Список возможных прав можно найти тут. Если пользователь разрешит доступ, к нам на redirect_uri прийдет нужный signed_request.
Например (при разработке FBML приложения):
В данном случае нам покажется стандартный FB диалог с запросом прав. В случае разрешения доступа вызовется callback('publish_stream,read_stream'), в противном случае — callback(null);
В FBJS есть объект Ajax, и в нем — свойство requireLogin. Если при запросе его выставить в true — ajax запрос будет успешным только после разрешения юзером доступа к своим данным. Например:
Здесь, как и в предыдущем способе, вызовется FB диалог. FBJS во многом ограничивает разработчика, в частности после парсинга нашего FBML ко всем переменным и функциям добавляется строка appAPPLICATIOPN_ID_, т. е. var ajax превращается в var app1234567890_ajax, alert — в app1234567890_alert. Хорошо есть console, фактически основной дебаггер. В будущем FB планирует отказаться от FBML приложений в пользу айфреймов и Javascript SDK, чем существенно упростит разработку приложений на табах.
После инициализации приложения нужно вызвать метод FB.login:
Диалог покажется в попапе браузера.
Во всех случаях появится примерно такой диалог:

Получив signed_request, его нужно распарсить. FB предлагает так (ф-ции включены в PHP SDK):
Функция parse_signed_request вернет нам ассоциативный массив, одним из ключей которого будет oauth_token. Далее можно использовать токен для доступа к Graph API, Old Rest API или FQL. Например:
При разработке FBML приложения на табе есть одна особенность: после разрешения пользователем доступа, получить signed_request с user_id можно только с ajax-запроса. В противном случае user_id будет равен profile_id (оба — айди текущего профиля (страницы)), и oauth_token будет «прикреплен» к странице, а не к профилю юзера.
Удачи!
Данные о текущем пользователе (или о текущем профиле) FB передает в параметре signed_request, а именно:
- algorithm — HMAC-SHA256;
- user_id — айди текущего пользователя;
- oauth_token — зашифрованная строка, которую можно использовать в дальнейшем для доступа к Graph API, Old Rest API или FQL;
- expires — когда истекает oauth_token;
- profile_id — появляется на табе профиля.
$_REQUEST['signed_request'] представляет собой конкатенацию подписи HMAC SHA-256, точки (.) и JSON объекта, упакованного в base64url. Выглядит примерно так (все слитно):
g2LAGH9BQ25BqO8-V5lP4Z74_DQ7U6AzWDGBpz-3yDg . eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImV4cGlyZXMiOjAsIm9hdXRoX3Rva2VuIjoiMTI4ODI1OTA3MTYxMTc3fGNlNmM1NTUwNDEyNDlhOGU4NjlmOTVlOC0xMDAwMDEzMzM0ODk4ACR8ZVRzd1d4WjR5b2pkQ2dHU0dUcWx0NFpvBXlBLiIsInVzZXJfaWQiOiIxMDAwMDEzMzM0ODk4NDQifQ
Для того, чтобы FB передавал нашему приложению signed_request, нужно указать это в настройках (т.к. на данный момент это бета фича):

После того, как пользователь разрешит доступ приложения к своим данным, мы будем получать signed_request в каждом запросе к нашему Canvas URL (откуда FB берет контент приложения). Есть несколько способов вызова такого диалога:
1. Редирект.
Редиректим пользователя на адрес:
https://graph.facebook.com/oauth/authorize? client_id=наш Application ID &redirect_uri=куда перейти после разрешения доступа &scope=какие права запрашивать
Список возможных прав можно найти тут. Если пользователь разрешит доступ, к нам на redirect_uri прийдет нужный signed_request.
2. FBJS метод Facebook.showPermissionDialog.
Например (при разработке FBML приложения):
Facebook.showPermissionDialog('publish_stream,read_stream', callback);
В данном случае нам покажется стандартный FB диалог с запросом прав. В случае разрешения доступа вызовется callback('publish_stream,read_stream'), в противном случае — callback(null);
3. Ajax.
В FBJS есть объект Ajax, и в нем — свойство requireLogin. Если при запросе его выставить в true — ajax запрос будет успешным только после разрешения юзером доступа к своим данным. Например:
var ajax = new Ajax(); ajax.responseType = Ajax.FBML; ajax.ondone = function(data) { console.log(data); } ajax.requireLogin = true; ajax.post("http://example.com/processAjax.php");
Здесь, как и в предыдущем способе, вызовется FB диалог. FBJS во многом ограничивает разработчика, в частности после парсинга нашего FBML ко всем переменным и функциям добавляется строка appAPPLICATIOPN_ID_, т. е. var ajax превращается в var app1234567890_ajax, alert — в app1234567890_alert. Хорошо есть console, фактически основной дебаггер. В будущем FB планирует отказаться от FBML приложений в пользу айфреймов и Javascript SDK, чем существенно упростит разработку приложений на табах.
4. Javascript SDK
После инициализации приложения нужно вызвать метод FB.login:
FB.login(function(response) { if (response.session) { // user successfully logged in } else { // user cancelled login } });
Диалог покажется в попапе браузера.
Во всех случаях появится примерно такой диалог:

Получив signed_request, его нужно распарсить. FB предлагает так (ф-ции включены в PHP SDK):
function parse_signed_request($signed_request, $secret) { // $secret - Application Secret list($encoded_sig, $payload) = explode('.', $signed_request, 2); // decode the data $sig = base64_url_decode($encoded_sig); $data = json_decode(base64_url_decode($payload), true); if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') { error_log('Unknown algorithm. Expected HMAC-SHA256'); return null; } // check sig $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true); if ($sig !== $expected_sig) { error_log('Bad Signed JSON signature!'); return null; } return $data; } function base64_url_decode($input) { // $input - base64url return base64_decode(strtr($input, '-_', '+/')); }
Функция parse_signed_request вернет нам ассоциативный массив, одним из ключей которого будет oauth_token. Далее можно использовать токен для доступа к Graph API, Old Rest API или FQL. Например:
Друзья: https://graph.facebook.com/ID/friends?access_token=... Ньюсфиды: https://graph.facebook.com/ID/home?access_token=... Стена: https://graph.facebook.com/ID/feed?access_token=...
При разработке FBML приложения на табе есть одна особенность: после разрешения пользователем доступа, получить signed_request с user_id можно только с ajax-запроса. В противном случае user_id будет равен profile_id (оба — айди текущего профиля (страницы)), и oauth_token будет «прикреплен» к странице, а не к профилю юзера.
Удачи!