Comments 55
В следующей статье опишу как оптимизировать запросы к Facebook Graph API для первого способа: с помощью Batch API и работы ассинхронных сокетов на PHP. У меня время загрузки данных от 1000 запросов к API сократилось до 20 секунд. При обычном переборе это бы заняло более 15 минут.
Статья разделяет типичное заблуждение: для получения пользовательских данных НЕ НУЖЕН offline_access
Если вам просто нужны данные — то берёте их просто и получаете, как обычно. offline_access нужен, если вы хотите выполнять действия от имени пользователя
Если вам просто нужны данные — то берёте их просто и получаете, как обычно. offline_access нужен, если вы хотите выполнять действия от имени пользователя
а можно ли без offline_access получить «вечный» access_token?
А зачем вам вечный access_token?
Информация доступна и при обычных сессионных токенах, согласно пермишнов, которые вы попросили у пользователя при авторизации.
Информация доступна и при обычных сессионных токенах, согласно пермишнов, которые вы попросили у пользователя при авторизации.
Об этом и написана статья, ведь если аппликации нужно постоянно работать с актуальными данными юзеров (даже в тот момент когда юзер не использует аппликацию), то нет никаких других способов, так как без offline_access нет актуального токена для доступа к пользовательским данным.
Эм, с чего вы это взяли?
Пользовательские данные (которые он разрешил отдавать приложению) вполне доступны без offline_access и «вечных» токенов.
Пользовательские данные (которые он разрешил отдавать приложению) вполне доступны без offline_access и «вечных» токенов.
то есть при устаревании access_token'а его обновление не требует никаких подтверждений от пользователя?
Эм.
Смотрите, после того, как пользователь авторизовал запрос, в котором вы указали какие именно пермишны вам нужны, у вас появляется право на чтение этих ресурсов. Вне зависимости от наличия сессии.
В начале каждой сессии работы с FB API вы просто получаете новый токен и работаете с ним. По этому токену — апи понимает, что это ваше приложение. А у них в системе авторизации как раз и хранится, к каким пользователям какой доступ у вас есть.
После этого вы берёте и просто выполняете запрос нужной информации, подписывая запрос текущим сессионным токеном.
Смотрите, после того, как пользователь авторизовал запрос, в котором вы указали какие именно пермишны вам нужны, у вас появляется право на чтение этих ресурсов. Вне зависимости от наличия сессии.
В начале каждой сессии работы с FB API вы просто получаете новый токен и работаете с ним. По этому токену — апи понимает, что это ваше приложение. А у них в системе авторизации как раз и хранится, к каким пользователям какой доступ у вас есть.
После этого вы берёте и просто выполняете запрос нужной информации, подписывая запрос текущим сессионным токеном.
спасибо!
Так про это и речь, что допустим нет у меня никакой сессии, юзер воопще уже месяц не заходил в аппликацию, а мне позарез нужены его актуальные данные. Тут нет никакого выбора как использовать либо offline_access, либо realtime update.
Вы ошибаетесь.
Вот так вы получаете актуальный access_token, суть сессионный. С его помощью у вас есть доступ ко всем данным, которые пользователи разрешили вам просматривать.
OAuth — это авторизационный протокол. Всё, что вам когда-либо было разрешено и до сих пор не запрещено вы можете получить, имея актуальный (живой) access_token.
graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE
Вот так вы получаете актуальный access_token, суть сессионный. С его помощью у вас есть доступ ко всем данным, которые пользователи разрешили вам просматривать.
OAuth — это авторизационный протокол. Всё, что вам когда-либо было разрешено и до сих пор не запрещено вы можете получить, имея актуальный (живой) access_token.
>>code=THE_CODE_FROM_ABOVE
Откуда этот код взять?
Откуда этот код взять?
developers.facebook.com/docs/authentication/ — вот тут всё в деталях описано
Ага, там в деталях описано, что этот код получается от юзера. Он его «приносит» с собой после аутентификации в фейсбуке. А если юзера не было месяц, то и кода нет.
habrahabr.ru/blogs/facebook/124195/#comment_4082353 — вот тут пример, который работает без сессии пользователя.
Кстати, увидел запрос и понял, что вы же получили access_token от приложения. В запросе нет ни одного параметра, который бы был уникален для каждого конкретного пользователя. Поэтому если продолжать разговор о вечном acces_token пользователя, полученным с помощью offline_access permission — это разные вещи.
Приведите пример этой разницы? Какую именно информацию из статьи вы не смогли бы получить без offline_access?
(этот грант — очень серьёзный, и я бы никогда без реальной необходимости его не запрашивал)
(этот грант — очень серьёзный, и я бы никогда без реальной необходимости его не запрашивал)
Я скажу даже больше — в моём коде приложение вообще никаких токенов от FB API не получает. Единственный токен который используется — сгенерирован кодом и выглядит как «appid|secret».
Но так или иначе, повторюсь, в вечных токенах нет ни одной причины (по крайней мере вы не привели пока ни одной таковой) для решения описанной в статье задачи.
Но так или иначе, повторюсь, в вечных токенах нет ни одной причины (по крайней мере вы не привели пока ни одной таковой) для решения описанной в статье задачи.
Писать пример мне лень, но, спасибо фейсбуку, можно поиграться с апи через
Упс, отправилось случайно
через developers.facebook.com/tools/explorer
Не давайте оффлайна. Получите токен и читайте инфу.
через developers.facebook.com/tools/explorer
Не давайте оффлайна. Получите токен и читайте инфу.
Может я чего-то недопонимаю, тогда у меня пару вопросов…
Ваш пример запроса сверху возвращает токен самой аппликации и вы хотите сказать, что с помощью него я смогу получать все данные юзера которые разрешено видеть этой аппликации? Если так, то тогда я воопще не понимаю зачем нужен offline_access. Не просто же так его придумали?
Ваш пример запроса сверху возвращает токен самой аппликации и вы хотите сказать, что с помощью него я смогу получать все данные юзера которые разрешено видеть этой аппликации? Если так, то тогда я воопще не понимаю зачем нужен offline_access. Не просто же так его придумали?
Дайте мне тогда минут 10 чтобы состряпать пример.
По поводу «зачем» — написал ниже habrahabr.ru/blogs/facebook/124195/#comment_4082310
Честно — не знаю. Но он мне не требовался никогда.
По поводу «зачем» — написал ниже habrahabr.ru/blogs/facebook/124195/#comment_4082310
Честно — не знаю. Но он мне не требовался никогда.
pastebin.com/yCcLrut7
Как пользоваться им:
1. Стягиваете php.sdk, кладёте его рядом с example.php
2. Прописываете свои appid + secret
3. Запускаете скрипт
4. Переходите по login
5. Авторизуете
6. Сбрасываете кэш/открываете в другом браузере и убеждаетесь, что можете получить информацию
ps: в 20 и 24 строках — просто подмените на свой nickname или uid
Как пользоваться им:
1. Стягиваете php.sdk, кладёте его рядом с example.php
2. Прописываете свои appid + secret
3. Запускаете скрипт
4. Переходите по login
5. Авторизуете
6. Сбрасываете кэш/открываете в другом браузере и убеждаетесь, что можете получить информацию
ps: в 20 и 24 строках — просто подмените на свой nickname или uid
Бррр, сбрасываете кэш == сбрасываете куки
После того как вы авторизируете приложение, то по ссылке login вас сначала направят в фейсбук, а от туда будет сразу редирект обратно с токеном.
Всё верно. Один раз пользователь должен авторизовать приложение. После этого пользователь может не ходить в ваше приложение никогда вообще, но права у вашего приложения так и останутся.
И все данные ваше приложение получит и без пользовательской сессии.
Собственно это мой код и делает.
И все данные ваше приложение получит и без пользовательской сессии.
Собственно это мой код и делает.
Пользовательская сессия (access_token) по-умолчанию имеет короткое время жизни, и пользователь должен её обновлять, без него Вы сами не сможете её обновить.
Чтобы сессия имела долгое время жизни, необходимо получить offline_access — именно это написано в доке.
Это я хотел объяснить.
Чтобы сессия имела долгое время жизни, необходимо получить offline_access — именно это написано в доке.
Это я хотел объяснить.
Выполняю последовательность:
1. Захожу на developers.facebook.com/tools/explorer/
2. Получить access_token
3. Разрешаю (права стандартные).
4. Запрос "/me" — получаю инфу о себе (убеждаюсь, что токен привязан к пользователю, id пользователя кстати есть в токене).
5. Выхожу из фейсбука (логаут).
6. Опять "/me" — ошибка.
7. Захожу в фейсбук.
8. Запрос "/me" — ошибка.
9. Получаю access_token с правами offline_access
10. Логаут
11. Запрос "/me" — успешно.
1. Захожу на developers.facebook.com/tools/explorer/
2. Получить access_token
3. Разрешаю (права стандартные).
4. Запрос "/me" — получаю инфу о себе (убеждаюсь, что токен привязан к пользователю, id пользователя кстати есть в токене).
5. Выхожу из фейсбука (логаут).
6. Опять "/me" — ошибка.
7. Захожу в фейсбук.
8. Запрос "/me" — ошибка.
9. Получаю access_token с правами offline_access
10. Логаут
11. Запрос "/me" — успешно.
Роман, я вам в третий раз даю ссылку на код habrahabr.ru/blogs/facebook/124195/#comment_4082353
Пожалуйста, изучите его.
Правда, повторять одно и то же более трёх раз становится уже совсем несмешно :-(
Пожалуйста, изучите его.
Правда, повторять одно и то же более трёх раз становится уже совсем несмешно :-(
По поводу вашего эксперимента — естественно /me будет давать ошибку.
А вы получайте информацию из "/username" или "/user_id". В этом случае апи вам отдаст всю информацию, в случае если пользователь авторизовал ваше приложение.
А вы получайте информацию из "/username" или "/user_id". В этом случае апи вам отдаст всю информацию, в случае если пользователь авторизовал ваше приложение.
Все запросы "/me" можно заменить на "/__мой_ид__" результат будет аналогичный.
Отнюдь. Если бы вы запустили мой код выше — то вы бы увидели, что для запросов "/user_id" для авторизованного (когда угодно) пользователя без живой сессии данные получить можно.
Пожалуйста, запустите код, а то разговор напоминает слепого с глухим.
Пожалуйста, запустите код, а то разговор напоминает слепого с глухим.
Дайте мне ид вашего приложения, я в нем авторизуюсь, а потом вы попробуете получить мои данные :)
146040145421160
www.facebook.com/dialog/oauth?client_id=146040145421160&redirect_uri=http%3A%2F%2Ffa-cebook.zerkms.ru%2Fexamples%2Fexample.php
Вот вам даже готовый урл, без редиректа оно не даст по идее ведь авторизоваться
Вот вам даже готовый урл, без редиректа оно не даст по идее ведь авторизоваться
Редирект был на 404, но приложение добавилось.
Мой ид 100002546363795.
Попробуйте получить инфу.
Мой ид 100002546363795.
Попробуйте получить инфу.
Френды:
Публичная часть профиля:
array(1) { ["data"]=> array(12) { [0]=> array(2) { ["name"]=> string(13) "Roman Voronin" ["id"]=> string(9) "768709678" } [1]=> array(2) { ["name"]=> string(12) "Vadim Petrov" ["id"]=> string(10) "1132705230" } [2]=> array(2) { ["name"]=> string(27) "Семен Васильев" ["id"]=> string(10) "1228603568" } [3]=> array(2) { ["name"]=> string(15) "Ivan Pesochenko" ["id"]=> string(10) "1306991321" } [4]=> array(2) { ["name"]=> string(16) "Dmitry Pleshakov" ["id"]=> string(15) "100001252861042" } [5]=> array(2) { ["name"]=> string(13) "Alexey Ishkov" ["id"]=> string(15) "100001429562921" } [6]=> array(2) { ["name"]=> string(15) "Sergey Akhmetov" ["id"]=> string(15) "100001490046287" } [7]=> array(2) { ["name"]=> string(13) "Irina Grandel" ["id"]=> string(15) "100001546721562" } [8]=> array(2) { ["name"]=> string(20) "Konstantin Gorlitsyn" ["id"]=> string(15) "100001846579290" } [9]=> array(2) { ["name"]=> string(31) "Сергей Мокроусов" ["id"]=> string(15) "100001876811246" } [10]=> array(2) { ["name"]=> string(12) "Ivan Bazetov" ["id"]=> string(15) "100002016464041" } [11]=> array(2) { ["name"]=> string(16) "Maxim Volosenkov" ["id"]=> string(15) "100002520373782" } } }
Публичная часть профиля:
array(7) { ["id"]=> string(15) "100002546363795" ["name"]=> string(14) "Roman Gogolev" ["first_name"]=> string(5) "Roman" ["last_name"]=> string(7) "Gogolev" ["link"]=> string(60) "http://www.facebook.com/people/Roman-Gogolev/100002546363795" ["gender"]=> string(4) "male" ["locale"]=> string(5) "ru_RU" }
И напоследок — если вы внимательно прочитаете все мои комментарии, то вы увидите, что я НЕ ГОВОРИЛ что вариант с offline_access работать не будет.
Я говорил, что offline_access — это избыточные права для рассматриваемой задачи и осторожные пользователи так много прав вам не дадут.
Я говорил, что offline_access — это избыточные права для рассматриваемой задачи и осторожные пользователи так много прав вам не дадут.
Расскажите, пожалуйста, для чего тогда этот offline_token.
Согласно описанию в developers.facebook.com/docs/reference/api/permissions/ — он необходим для выполнения действий от имени пользователя. Ни разу его не использовал, если честно, потому что и без него всё всегда доступно.
offline_access — Enables your app to perform authorized requests on behalf of the user at any time. By default, most access tokens expire after a short time period to ensure applications only make requests on behalf of the user when the are actively using the application. This permission makes the access token returned by our OAuth endpoint long-lived.
Переводится примерно так:
Разрешает Вашему приложению выполнять авторизованные запросы от имени пользователя в любое время. По-умолчанию, большинство access-токенов экспарятся после непродолжительного периода, чтобы быть уверынным, что приложения делают запросы от имени пользователя только когда он пользуется этим приложением. Этот пермишен делает access-токен долгоживучим.
Переводится примерно так:
Разрешает Вашему приложению выполнять авторизованные запросы от имени пользователя в любое время. По-умолчанию, большинство access-токенов экспарятся после непродолжительного периода, чтобы быть уверынным, что приложения делают запросы от имени пользователя только когда он пользуется этим приложением. Этот пермишен делает access-токен долгоживучим.
для фонового чтения ресурсов, на которых нет реалтайм апдейдов, например
Для каких, например, ресурсов может не хватать обычных сессионных токенов и необходим offline_access?
Например, пользователь не заходил неделю, а вашему приложению нужен его список друзей. В документации есть в связи friends запись о валидном токене. У вас токен пользователя истекает намного раньше.
Согласен, токен не нужен для многих полей. Но не для всех так.
Согласен, токен не нужен для многих полей. Но не для всех так.
Антон, я даю ссылку на этот комментарий уже в четвёртый раз: habrahabr.ru/blogs/facebook/124195/#comment_4082353
В том коде — получение френдов без offilne_access
В том коде — получение френдов без offilne_access
Прости, не видел новые комментарии, пока было открыто окно. Я изучу опыт в приложении, а также посмотрю всю информацию, что же такое дает offline_access. Пока понятно что работает и то и другое.
понятно, есть два вида access_token — с сессией и для приложения. для получения первого требуется, чтобы пользователь был залогинен, второй же формируется банально как "#{appId}|#{apiSecret}" и по нему доступны не все данные, в частности получить «user_id/home» не даёт с ошибкой 'You can only access the «home» connection for the current user.', «me/home» — 'An active access token must be used to query information about the current user.'.
offline_access`у всё-таки быть?
offline_access`у всё-таки быть?
Я не отрицаю, что ситуации, когда ему быть бывают.
Очевидно, что для эндпоинта home нужна сессия, потому что существует только me/home, но не uid/home.
Хотя я и не представляю ситуации, когда чужому приложению нужно знать, что происходит на моей стене
Именно поэтому я никогда не авторизую приложения, которым нужен оффлайн аксес :-)
А то так не долго до того, что все приложения будут без разбора просить и оффлайн, и read_mailbox, чтобы читать и стену, и приватные сообщения :-)
Очевидно, что для эндпоинта home нужна сессия, потому что существует только me/home, но не uid/home.
Хотя я и не представляю ситуации, когда чужому приложению нужно знать, что происходит на моей стене
Именно поэтому я никогда не авторизую приложения, которым нужен оффлайн аксес :-)
А то так не долго до того, что все приложения будут без разбора просить и оффлайн, и read_mailbox, чтобы читать и стену, и приватные сообщения :-)
ps: в строке с френдами написано Any valid access_token.
Т.е. любой токен, которому были даны пермишны.
В случае с приложением этот токен может быть банальной строкой «appid|secretid»
Т.е. любой токен, которому были даны пермишны.
В случае с приложением этот токен может быть банальной строкой «appid|secretid»
Sign up to leave a comment.
Оптимизируем запросы к Facebook Graph API с помощью Real-Time Updates