Как получить access_token в signature_request в приложении canvas, если уже авторизованному пользователю требуются дополнительные разрешения сейчас? - PullRequest
1 голос
/ 13 января 2012

Давайте предположим следующую ситуацию для приложения canvas:

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

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

Не требуется диалоговое окно разрешений для того же пользователя, приходящего в приложение в следующий раз, так как подписанный запрос содержит 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

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

ОБНОВЛЕНИЕ:

Обмен хорошим методом: сохраните набор разрешений вместе с access_token, с которым он был получен.например.Если текущие разрешения - «basic_details-birthday-publish» (давайте назовем это 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 каждого пользователя с помощью API "/ me / permissions".

Ответы [ 8 ]

5 голосов
/ 13 января 2012

Это будет двухэтапный процесс:

  1. Проверьте, предоставил ли пользователь вам все необходимые разрешения, отправив запрос к пути Graph "/ me / permissions"

  2. Если пользователь не предоставил вам все необходимые разрешения, вам нужно пройти обычный процесс Разрешить / Запретить, но на этот раз с новыми разрешениями, добавленными в параметр "scope".

Редактировать _: Единственный надежный способ проверки разрешений, который я знаю, - это вызов /me/permissions.

3 голосов
/ 20 января 2012

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

<code><?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)).'
'; } function get_app_access_token ($ id, $ secret) { $ token_url = "https://graph.facebook.com/oauth/access_token?". "client_id =". $ id. "& client_secret =". $ секрет. "& Grant_type = client_credentials"; return file_get_contents ($ token_url); }

Подробнее об этом см. В документации Обновления в реальном времени .

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

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" и проверять наличие ошибок, связанных с разрешениями, и действовать в соответствии с этим!

2 голосов
/ 16 января 2012

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

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

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

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

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

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

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

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

1 голос
/ 17 января 2012

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

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

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

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

0 голосов
/ 25 октября 2013

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

Сохраните набор разрешений вместе с access_token, с которым он был получен.например.Если текущие разрешения - «basic_details-birthday-publish» (давайте назовем это 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 каждого пользователя с помощью API "/ me / permissions".

0 голосов
/ 18 января 2012

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

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

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

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

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

перейти к https://developers.facebook.com/

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

нажмите настройки -> вкладка Auth Dialog в левом меню. и выберите необходимые права доступа, которые позволят всем пользователям наверняка, зайти на вашу страницу с необходимыми разрешениями,

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

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

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

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

удачи

0 голосов
/ 18 января 2012
$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);

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

...