2012-01-13 1 views
1

Давайте предположим следующую ситуацию для холста приложения:Как получить access_token в signed_request в приложении холста, если уже авторизованный пользователь нуждается в дополнительных разрешениях сейчас?

I) День 1: - Facebook приложение создано, которое нуждается в read_stream,publish_stream,offline_access разрешения. Когда в первый раз приходит приложение , authorize вызывает перенаправление пользователя на экран разрешения ALLOW/DENY, и когда пользователь разрешает его перенаправляет пользователя обратно на холст-адрес.

URL-адрес холста имеет access_token в подписанном запросе в запросе параметров, которые затем могут использоваться для запуска приложения.

Не требуется диалог с разрешением для того же пользователя, который приходит в приложение следующего времени, так как signed_request содержит acess_token, если у пользователя было авторизованное приложение в прошлом.

код выглядит следующим образом:

if(access_token received from signed request) 
// do something with user information 
else 
// redirect user for authorization flow 

II) День 2: - Теперь, скажем, я хочу добавить еще один разрешение в мой список, user_birthday read_stream, publish_stream, offline_access, user_birthday` Теперь следующее логика будет иметь проблемы

if(access_token received from signed request) 
    // do something with user information <-- the access_token does not have new permission 
    else 
    // redirect user for authorization flow 

Как это дополнительное добавление разрешения было бы решать эффективно, так как API вызовы влияют на производительность приложения? я не хотел бы использовать что-то вроде:

https://graph.facebook.com/me/permissions?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 

Каждый раз, когда нагрузки приложений для проверки прав доступа, относящиеся к маркеру.

UPDATE:

Sharing хороший метод: магазин разрешение установить вместе с access_token, с которым он был получен. например. Если текущие разрешения являются «basic_details-день рождения публиковать» (назовём его 1), Хранить access_token и разрешение установить в качестве

user | access_token | perm_set 
Dhruv  sdfsdfsdf  1 

Теперь в настройках, когда вам нужно задать для нового разрешения, создать новый набор разрешений «basic_details-birthday-publish-checkins» (позволяет называть его 2),

тогда вам нужно отобразить диалог разрешений только для пользователей, у которых есть токен доступа с perm_set = 1, а не для пользователей, которые уже имеют perm_set = 2, это избавит вас от необходимости проверять access_token каждого пользователя с помощью «/ me/permissions» api.

ответ

0

Реализация предложения.

Сохраните набор разрешений вместе с access_token, с которым он был получен. например. Если текущие разрешения являются «basic_details-день рождения публиковать» (назовём его 1), Хранить access_token и разрешение установить в качестве

user | access_token | perm_set 
Dhruv  sdfsdfsdf  1 

Теперь в настройках, когда вам нужно задать для нового разрешения, создать новый набор разрешений «basic_details-birthday-publish-checkins» (позволяет называть его 2),

тогда вам нужно отобразить диалог разрешений только для пользователей, у которых есть токен доступа с perm_set = 1, а не для пользователей, которые уже имеют perm_set = 2, это избавит вас от необходимости проверять access_token каждого пользователя с помощью «/ me/permissions» api.

5

Было бы процесс 2 шага:

  1. Проверьте, если пользователь предоставил вам все необходимые разрешения путем выдачи запроса на путь Graph «/ Me/разрешение»

  2. Если пользователь не предоставил вам все необходимые разрешения, необходимые для прохождения обычного процесса Allow/Deny, но на этот раз с новыми правами, добавленными в параметр «scope».

Edit_: Единственный надежный способ я знаю, для проверки разрешений является вызов/Me/разрешения.

+0

Дхрув сказал, что он не хочет делать эту конкретную проверку. – DMCS

+0

Похоже, именно поэтому вы также включили его в свой ответ? –

+0

lol, Просто повторить, что это лучший способ. Как вы можете видеть, я сказал, что один из моих трех - тот, который он сказал, что он не хотел этого делать. :) – DMCS

2

У вас есть три варианта, и один из них - тот, который вы уже сказали, что вы не хотите делать.

  1. Проверить me/permissions и петля через, чтобы увидеть, если они все еще там.

  2. попробуйте/поймайте каждый вызов API и следите за полученной ошибкой (см. http://fbdevwiki.com/wiki/Error_codes), чтобы узнать, есть ли это # ​​10 API_EC_PERMISSION_DENIED. Если это так, попросите пользователя снова получить разрешения.

  3. Напишите свое приложение, чтобы оно было обратно совместимо со старым набором разрешений, поэтому только новые функции в нем отображаются для пользователей, которым предоставлены более новые разрешения. Конечно, вам нужно будет попробовать/уловить каждый вызов API, чтобы узнать, какие части вашего приложения вам нужно скрыть/показать.
1

Во-первых, я укажу очевидное. Вы должны использовать конечную точку /me/permissions. Это единственный способ узнать наверняка, является ли токен доступа действительным и имеет все необходимые разрешения. Поскольку вы сказали, что хотите, чтобы решение, которое не попадало в эту конечную точку каждый раз, когда приложение загружено, я продолжу.

Единственный способ, которым я могу думать, не проверять вызов API /me/permissions, - это отслеживать разрешения на вашем собственном сервере с простой таблицей, сопоставляющей user_id с разрешениями для пользователя. Когда новый пользователь авторизован, вы добавляете строку в таблицу базы данных для этого идентификатора пользователя fb и список разрешений, разрешенных ими. Теперь, когда они вернутся, вы можете получить signed_request и искать в своей таблице, есть ли у них все необходимые разрешения. Если они этого не сделают, вы предложите им разрешить дополнительные разрешения и обновить таблицу, если они предоставят вам эти разрешения.

Поскольку вы уже запрашиваете offline_access, я предполагаю, что вы все равно сохраняете токены доступа, поэтому добавление другой таблицы для списка разрешений на токен доступа похоже на то, что это не будет слишком большим бремя.

Есть некоторые очевидные подводные камни с этим дизайном (несоответствие с FB), но если ваша основная цель состоит в том, чтобы избежать конечной точки /me/permissions, это должно сработать для вас.

-1
$facebook = new Facebook(array(
       'appId' => 'xxxxxx', 
       'secret' => 'xxxxx', 
       'cookie' => true, 
      )); 
$code = @$_REQUEST["code"];//only get after log in into the app 
if(empty($code)) 
{ 
$dialog_url  = "http://www.facebook.com/dialog/oauth?client_id=" 
       . $app_id . "&redirect_uri=" . urlencode($canvas_page_url)."&scope=email,read_requests,offline_access,read_mailbox,user_relationships,user_likes,user_online_presence,user_activities,user_status,user_groups,manage_pages,friends_status,read_stream,friends_photos,publish_stream"; 
echo("<script> top.location.href='" . $dialog_url . "'</script>"); 
} 
$token_url   = "https://graph.facebook.com/oauth/access_token?client_id=" 
       . $app_id . "&redirect_uri=" . urlencode($canvas_page) . "&client_secret=" 
       . $app_secret . "&code=" . $code; 
$access_token = @file_get_contents($token_url); 

попробуйте с вышеуказанным кодом и перезагрузите приложение, после чего он отобразит всплывающее окно, чтобы получить доступ к дополнительным разрешениям, которые вы добавляете.

+0

Этот ответ неверен и вообще не использует signed_request. – DhruvPathak

+0

никогда! потому что я использую этот код в настоящее время в своем приложении, и он отлично работает. Можно использовать приложение accesstoken поколение таким образом, не используя метод подписанного запроса. Дополнительное подтверждение см. в http: //developers.facebook.com/blog/post/480/ –

+0

этот код заставит приложение запрашивать токен доступа и через поток аутентификации 0Auth2.0 каждый раз, когда пользователь приходит в приложение. С signed_request, который не требуется, поскольку пользователь, прошедший аутентификацию информации в прошлом, получает информацию, подобную информации пользователя, и access_token в signed_request. Подробнее здесь: http://developers.facebook.com/docs/authentication/signed_request/ – DhruvPathak

0

Все ответы здесь основаны на старой системе auth facebook, в которой, когда не существует допустимого параметра signed_request, вы перенаправляете пользователя на oauth url с параметром scope, который содержит требуемые разрешения.

Если не запрашивается разрешение автономного доступа, то нет проблем, поскольку каждый токен доступа пользователя будет недействительным через два часа, поэтому после двух часов изменения параметра области с новыми разрешениями каждый новый визит будет перенаправлен на oauth с новой областью, так что facebook справится с этим правильно.

Поскольку вы уже приняли автономные права и вам это нужно, то accesstokens пользователей не будет легко invalitated (если только пользователь меняет пароль, или деактивирует приложение), решение предшествующее не будет работать правильно,

I согласитесь, что проверка ошибок разрешений в вызовах graph api - это способ проверки того, что пользователь не разрешил вам то, что вы попросили, а затем перенаправить пользователя, чтобы предоставить ему или ей гарантии ваши разрешения. Это приемлемо, но ненужного

Потому что теперь, вы можете сделать ваши необходимые разрешения на странице настроек facebook приложения, более конкретно

пойти https://developers.facebook.com/

и выберите приложение.

Настройки кликов -> вкладка «Автодиалог» в левом меню. и выберите ваши разрешения, которые позволят всем пользователям, конечно, прийти на вашу страницу с необходимыми разрешениями,

Однако вы не можете использовать какое-либо расширенное разрешение здесь.

Таким образом, единственный возможный ответ на вашу проблему - удалить все ваши токены доступа сразу, поскольку это позволит всем возвращающимся пользователям перенаправляться в новое диалоговое окно разрешений.

Но это решение предоставит вам образы о получении информации о вашей пользовательской базе, , чтобы преодолеть эту проблему, вы можете запускать ее только при посещении пользователем страницы, поэтому после удаления его пользователя tokeni, возможно, стр. Но вы должны сохранить дополнительный бит для каждого пользователя, удерживая это, потому что они подвергаются этой операции удаления токена доступа. Если пользователь не подвергается этой операции и не посещает ваше приложение, просто удалите токен доступа и перенаправьте пользователя на страницу oauth с новыми разрешениями, если пользователь уже это сделал, тогда нет никаких проблем для такого рода вещей.

Таким образом, мой ответ - вышеупомянутые альтернативы. Но самый сложный и элегантный способ решения этой проблемы - запрашивать разрешения, когда пользователь взаимодействует с вашим приложением, чтобы использовать эту функциональность вашего приложения, требующую разрешения, о котором мы говорим. Таким образом, скорость CTR для oauth будет повышаться, так как вы не сделаете своего пользователя бояться длины начальных разрешений, о которых вы просите. Пользователям будет больше информации об использовании вашего приложения. Всякий раз, когда им нужно делать замечательные вещи в своем приложении, вы можете затем любезно попросить прекрасное разрешение.

удачи

3

Ну, самое эффективное решение потребовало бы, что предложил @Jeff плюс использования в режиме реального времени API.
ШАГ 1: Создайте таблицу разрешений, чтобы сохранить права пользователя, когда пользователь «подключается» к вашему приложению в первый раз.
ШАГ 2: подписаться на объект разрешения, например:

<?php 
require '../src/facebook.php'; 

$facebook = new Facebook(array(
    'appId' => 'APP_ID', 
    'secret' => 'APP_SECRET', 
)); 

$app = get_app_access_token("APP_ID", "APP_SECRET"); 
parse_str($app); 

$realtime_params = array(
    'object'=>'permissions', 
    'fields'=>'read_stream,publish_stream', // most recent permissions required by your app 
    'callback_url'=>'CALLBACK_URL_HERE', 
    'verify_token'=>'STRING_THAT_SHOULD_BE_PRESENT_IN_THE_CALLBACK_PAGE_TOO', 
    'access_token'=>$access_token 
); 

try { 
$res = $facebook->api("/APP_ID/subscriptions", "post", $realtime_params); 
} catch (FacebookApiException $e) { 
echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>'; 
} 
function get_app_access_token($id,$secret) { 
    $token_url = "https://graph.facebook.com/oauth/access_token?" . 
        "client_id=" . $id . 
        "&client_secret=" . $secret . 
        "&grant_type=client_credentials"; 
    return file_get_contents($token_url); 
} 

Подробнее об этом в документации Real-time Updates.

ШАГ 3: Ваша страница обратного вызова должен обрабатывать запрос на почту, посланную Facebook, если пользователь отозвана один из разрешений (например, удалены publish_stream разрешения); в этом случае, Facebook будет посылать вам что-то вроде (после декодирования запроса см here):

Array 
(
    [object] => permissions 
    [entry] => Array 
     (
      [0] => Array 
       (
        [uid] => 100003355152933 
        [id] => 100003355152933 
        [time] => 1327005647 
        [changed_fields] => Array 
         (
          [0] => publish_stream 
         ) 

       ) 

     ) 

) 

Независимо от того, что было изменено, я бы использовал выше запрос в качестве триггера, запроса /user_id/permissions соединение и обновление таблица разрешений.

Теперь у вас есть два случая:

if(access_token received from signed request) 
    if(permissions from table are full) 
     // do something with user information 
    else 
     // ask for missing permission and update permissions table 
else 
    // redirect user for authorization flow 
    // upon full authorization, save to the permissions table too 

Очевидно, что было сказано в других ответах следует использовать слишком. Вы всегда должны использовать предложения «try ... catch» и проверять ошибки, связанные с разрешением, и действовать на это!

+1

+1 для этого (ИМХО) очень хорошее решение! –

+0

@ BjörnKaiser, спасибо. Просто добавьте, при использовании обновлений в реальном времени, скорее всего, вам придется ставить в очередь ваши задачи, которые не являются самыми сильными функциями PHP! – ifaour

1

Не забывайте, что вы также можете использовать javascript SDK для запроса разрешений. Javascript SDK фактически делает все встроенным. Вы можете вызвать функцию «login» с параметрами разрешений, которые вам нужны, если они уже предоставлены, ничего не происходит.

Как и другие, вы можете запросить график для/me/permissions, но используйте метод api javascript для получения информации. Поэтому, если вы не хотите сохранять разрешения, предоставленные пользователем, и подписаться на обновление api в реальном времени, чтобы убедиться, что они остаются в курсе событий, вы можете использовать javascript api для выполнения всех встроенных, с клиентской стороны.

Вы в значительной степени избавляетесь от того, что ваш сервер играет какую-либо роль и связывает пользователя напрямую с Facebook через javascript. Facebook на самом деле делает некоторое кэширование на стороне клиента, поэтому вызовы могут быть мгновенными.

Это сообщение в блоге в Facebook о запросе на отсутствие разрешений. https://developers.facebook.com/blog/post/576/