Подтвердить что ты не робот

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

У меня есть служба WCF, которая работает в IIS 7.5 и VS 2010. Эта служба имеет некоторые методы, которые используют Facebook С# SDK (версия 4.1, не последний), чтобы выполнить некоторые GET и POST из/в Facebook. Поскольку Facebook скоро удалить offline_access, я должен обработать ситуацию, когда токен доступа истек.

Я понял, как выполняется аутентификация (чтобы получить код и после того, как код получил токен доступа), чтобы использовать Graph API для получения информации Facebook (как представлено здесь).

У меня есть два вопроса:

  • Когда мой метод службы вызывается, и я извлекаю токен соответствующий пользователь из моей БД, есть ли способ узнать, является ли токен доступа истек или нет?
    У меня читать, что при вызове API Facebook и истечении срока доступа маркер доступа генерируется следующее исключение: OAuthException. Но есть ли лучший способ обнаружить истечение? Я не хочу, чтобы
    • Вызвать API Facebook
    • Обработать исключение
    • Замените токен доступа и, наконец,
    • Повторите первоначальный вызов с новым токеном доступа.
  • Возможно ли прозрачно обновить токен доступа пользователя (сохранить его также в БД) и продолжить обработку метода службы? В этот ресурс отсутствует важная часть ( "Обновить токен доступа" ) (объявлена ​​как [TODO])

Я хотел бы получить следующую схему в реализации Сервисного метода:

sc = SocialNetworkAccountDao.GetByUser(user)

isExpired = call method to check if the sc.token is expired.

if (isExpired)

{

  newToken = call method for getting new access token

  sc.token = newToken;

  SocialNetworkAccount.Update(sc);

}

Facebook = new Facebook (sc.token)

Facebook.Post( ..... )

--

Процесс связи с диалогом QAuth является асинхронным (выполняется перенаправление), а связь с URL-адресом токена доступа для получения токена доступа выполняется синхронно.

Заключительный вопрос:

  • Есть ли способ, по которому сервисный метод ждет нового токена доступа, мы извлекать из запроса/обратного вызова с помощью Facebook для того, чтобы продолжить позже с новым токеном доступа?
4b9b3361

Ответ 1

Я не знаю о С# SDK, но все файлы facebook SDK в основном являются просто обертками для HTTP-запроса на графике разных URL-адресов.

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

Аутентификация на стороне клиента возвращает краткосрочный токен (около 2 часов), но вы можете использовать новую конечную точку, чтобы заменить "offline_token" ". Вы можете использовать это с еще доступными токенами доступа.

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

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

Вы также можете использовать официальную документацию для Обработка недействительных и истекших токенов доступа. Если SDK С# не подходит для вас, вы можете просто реализовать его самостоятельно, для своих нужд, должно быть довольно легко.

Ответ 2

Вы должны действительно обновить cdk cdk до последней версии - с течением времени они исправят множество проблем.

Обновление токена
Это наш код, который обрабатывает сам вызов обновления (С# sdk ver 6.0.16, но это также должно работать и с более ранними версиями):

    /// <summary>
    /// Renews the token.. (offline deprecation)
    /// </summary>
    /// <param name="existingToken">The token to renew</param>
    /// <returns>A new token (or the same as existing)</returns>
    public static string RenewToken(string existingToken)
    {
        var fb = new FacebookClient();
        dynamic result = fb.Get("oauth/access_token", 
                                new {
                                    client_id         = FACEBOOK_APP_ID,
                                    client_secret     = FACEBOOK_APP_SECRET,
                                    grant_type        = "fb_exchange_token",
                                    fb_exchange_token = existingToken
                                });

        return result.access_token;            
    }

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

Согласно Facebook, вы должны позвонить продлению до одного раза в день. (https://developers.facebook.com/roadmap/offline-access-removal/)

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

По-видимому, он не вызывает его один раз в день, но называет его один раз для токена.

Facebook не позволит вам возобновить токеновый токен. См. "Сценарий 4:" на странице офлайн-доступ к удалению

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

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

Обработка срока действия
В нашем текущем использовании нам не требовалось отслеживать время истечения срока действия, так как весь доступ начинается с клиента, который его проверяет, но в том же доступе кода result.access_token он может получить доступ к result.expires, который возвращает количество секунд оставшееся на этом вновь приобретенном токене (должно быть близко к 5 мил = > 60 дней)).

В любом случае, я не уверен, что есть способ получить время истечения срока от токена, не делая другого вызова процесса auth. Я знаю, что Facebook Debugger возвращает это, но это действительно не помогает.

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

Ответ 3

Время до истечения срока действия

Короткий ответ: вы получаете секунды до истечения срока действия, но С# api, похоже, не выставляет его.

Согласно этой документации в facebook, вы получите количество секунд, пока токен не закончится как параметр, когда вы получите токен. В документации указан формат ответа:

access_token=USER_ACESS_TOKEN&expires=NUMBER_OF_SECONDS_UNTIL_TOKEN_EXPIRES 

Это подтверждается проектом RFC для Ouath 2, в котором говорится, что ответы должны содержать время истечения.

К сожалению, это прямо противоречит документации С# SDK, в которой говорится здесь, что

Невозможно определить, истек ли токен доступа без запроса в Facebook. По этой причине вы всегда должны предполагать, что токен доступа может быть истек при обращении к Facebook.

Это неверно. Если вы посмотрите на источник SDK С#, то объект, созданный sdk для ответа OAuth, явно содержит (к сожалению, как приватную переменную) следующий code

    /// <summary>
    /// Date and Time when the access token expires.
    /// </summary>
    private readonly DateTime _expires;

Итак, у него есть данные, но по какой-то причине он не раскрывает его (по крайней мере там, я не смотрел дальше). Я бы сказал, что либо выкопайте библиотеку больше, и посмотрите, где ее где-то выставили, вилка и патч ее на github (я считаю, что это однострочное изменение), или используйте рефлексию для чтения частной переменной в вашем собственном коде.

Продолжая обрабатывать метод службы и обновлять токен

Короткий ответ: Может быть. Если вы знали, что токен истек, вы можете obviosuly получить новый до запроса.

Если вы этого не сделаете, вы можете, но вам нужно обработать ваш запрос. Теоретически это не означает, что вам нужно обрабатывать исключение, просто посмотрите код статуса http (который будет одним из 400-х, возможно, 403 запрещен), однако С# webrequest методы интерпретируют не 200 статус c как события, которые создают исключение. Поскольку API использует этот механизм для совершения вызовов, вы получаете только исключение, когда они терпят неудачу.

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

Конечно, после обработки исключения.

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

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

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

Фактически невозможно использовать async/wait или что-то подобное, чтобы дождаться вашего запроса на новый токен. Проблема, обновляющая токен API, не требует, чтобы вы могли ждать ответа, фактически запуская что-то, что в конечном итоге вызывает отдельный запрос на получение. Facebook API requests Обратите внимание, что, хотя приведенная выше диаграмма относится к тому, когда пользователь впервые регистрируется, одна и та же последовательность происходит примерно на неудавшемся вызове, но начинается с перенаправления.