我有它运行在IIS 7.5和VS 2010中的WCF服务这个服务里面有一些方法在内部使用的Facebook C#SDK (4.1版本,而不是最新的),以便从/向Facebook执行一些GET和POST。 由于Facebook将很快删除了offline_access
我必须处理这种情况的访问令牌已过期的情况。
我已经明白中进行认证(为了获取代码,并具有代码以获得访问令牌后),以便使用图形API用于获取Facebook的信息(如呈现的方式在这里 )。
我有两个问题:
- 当我的服务方法被调用,检索到相应的用户的令牌从我的数据库,是有办法知道,如果访问令牌已过期或不?
我已阅读 ,当执行一个Facebook的API调用和访问令牌到期,则下面的异常被抛出: OAuthException
。 但是,有没有更好的办法来检测何时到期? 我不想
- 调用Facebook的API
- 处理异常
- 续订访问令牌,最终
- 重复使用新的访问令牌初始呼叫。
- 是否有可能延长用户的访问令牌透明(也存储在它的数据库),并继续处理服务的方法? 在此资源,重要的(“续订访问令牌”)部分缺失(声明为[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,以便与新的访问令牌后继续获取新的访问令牌?
我不知道C#的SDK,但所有的Facebook SDK的基本上是为HTTP请求到图形不同的URL只是包装。
如果您使用服务器端的认证流程,那么你应该得到一个长寿命令牌(约60天),你得到的过期时间吧,期满后需要重新认证的用户,有没有办法来延长令牌。
客户端认证返回一个短暂的令牌(约2小时),但你可以使用新的端点提供更换“offline_token”脸谱。 您只能使用与仍然有效的访问令牌。
此外,不管是什么,你总能得到,当你得到一个访问令牌,除非它是不具有到期日期的应用程序令牌“过期”时间。
在这两种情况下,如果你得到一个长寿命的令牌,你可以将其存储在数据库中,并用它在服务器端,但要注意的是,令牌可以仍然可以为无效的一些原因。
您还可以使用官方的文档处理无效和过期的访问令牌 。 如果C#SDK不为你很好地工作,那么你可能想只实现它自己,根据自己的需要,应该很容易。
你真的应该更新C#SDK到最新版本 - 他们解决了很多问题,随着时间的推移..
续订令牌
这是我们的代码来处理的更新调用本身(C#SDK版本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的调试器返回这一点,但并没有真正帮助..
续订无效令牌
这将无法正常工作 ,你会得到任何错误的解释为这里尝试续订到期的/无效的令牌时。
记得把它到期之前续约,并记住,当你致电过期(或任何其他形式的无效)续约,你会得到一个错误,需要处理它(我们处理它,我贴的代码外)。
时间,直到过期
简短的回答:你得到秒,直到它过期,但C#API似乎没有揭露它。
根据这个 Facebook的文档,你得到的秒数,直到当你得到令牌的令牌到期的paramater。 该文件列出了响应格式为:
access_token=USER_ACESS_TOKEN&expires=NUMBER_OF_SECONDS_UNTIL_TOKEN_EXPIRES
这是由草案备份RFC为Ouath 2它说的响应应该包含到期时间。
不幸的是,它直接由规定的C#SDK文档矛盾在这里说
有没有办法来确定是否访问令牌未做给Facebook请求过期。 出于这个原因,你必须假定,一个访问令牌可以提出请求给Facebook时到期。
这不是真的。 如果你看看C#SDK源,对象该SDK创建了OAuth的响应明确包含(遗憾的是作为一个私有变量)下面的代码
/// <summary>
/// Date and Time when the access token expires.
/// </summary>
private readonly DateTime _expires;
因此,它有数据,但由于某种原因没有公开它(至少在那里,我没有看进一步大幅)。 我想说无论是图书馆多转转挖,看看它的地方暴露出来,叉子和修补它在github上(我相信这是一个换线),或使用反射来阅读自己的代码的私有变量。
继续处理服务的方法和更新令牌
简短的回答:也许吧。 如果你知道令牌过期后,你可以得到obviosuly请求之前一个新的。
如果不这样做,比你还挺可以,但你需要处理您的请求失败。 从理论上讲,这并不意味着你需要处理的异常,只是看在HTTP状态代码(这将是一个在400S大概403禁止),但是C#的WebRequest的方法interpets非200个状态的C作为引发异常的事件。 由于API使用这个机制来拨打电话,你只有当他们没有得到一个异常。
是否有服务的方法来等待我们从获取新的访问令牌的方式
当然,在你处理异常。
一旦发生这种情况,异步,你将获得一个新的身份验证令牌。 所以,你可以捕捉异常后,等待一定的时间,如果你得到该用户的新的令牌检查,如果是重试。 如果继续等待和检查。 请确保您有重试的最大次数和时间来等待一个最高限额。 拉数据库来检查的变化是有点低效的,所以你可能要挑你检查的仔细变化的时间间隔,并可能使其成倍后退 。
其他的,更有效的(单个服务器),但复杂的方式,是有得到回调与身份验证令牌引发事件,并有重试逻辑监听这些事件的系统。
当因为凭证已过期您的代码获得了异常,在catch块做将重做请求,然后将其添加为一个事件侦听器AUTH事件的功能。 具备的功能检查,该事件是针对谁要求的情况下,如果是,发出请求的用户一个新的身份验证令牌。 再次,记得有一个最大的重试次数。
这是不可能的实际使用异步/等待或类似的东西等待你请求一个新的令牌cmplete。 这个问题,刷新API令牌不要求,你可以等待的,其实际触发一些响应,并最终导致制作一个单独的GET请求
注意,虽然上面的图是当用户第一次登录时,相同的顺序大致发生在呼叫失败,但它与重定向开始。
文章来源: How to transparently renew the Facebook access token while processing a service method which uses Facebook API calls?