14 c# security facebook token facebook-c#-sdk
我有一个在IIS 7.5和VS 2010中运行的WCF服务.此服务有一些方法在内部使用Facebook C#SDK(版本4.1,而不是最新版本),以便从/向Facebook执行一些GET和POST.由于Facebook将很快删除了offline_access我要处理,其中一个访问令牌已过期的情况.
我已经了解了执行身份验证的方式(为了获取代码并在获取访问令牌之后),以便使用Graph API获取Facebook信息(如此处所示).
我有两个问题:
OAuthException.但有没有更好的方法来检测到期?我不想我想在服务方法的实现中实现以下方案:
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( ..... )
--
Run Code Online (Sandbox Code Playgroud)
与QAuth对话通信的过程是异步的(执行重定向),并且与访问令牌url的通信以获得访问令牌,这是同步执行的.
最后的问题:
Nit*_*mer 14
我不知道C#SDK,但所有facebook SDK基本上只是http请求图表不同网址的包装.
如果您使用服务器端身份验证流程,那么您应该获得一个长期存在的令牌(大约60天),并且您获得它的到期时间,当它到期时您需要重新验证用户,没有办法扩展令牌.
客户端身份验证返回一个短期令牌(大约2小时),但您可以使用提供的新端点 facebook来替换"offline_token".您只能将其用于仍然有效的访问令牌.
此外,无论如何,当您获得访问令牌时,您始终会获得"过期"时间,除非它是没有过期日期的应用程序令牌.
在任何一种情况下,如果您获得一个长期存在的令牌,您可以将其存储在数据库中并在服务器端使用它,但请注意,由于多种原因令牌仍然无效.
您还可以使用处理无效和过期访问令牌的官方文档.如果C#SDK不适合您,那么您可能希望自己实现它,为了您自己的需要,应该非常简单.
Jon*_*son 12
您应该将c#sdk更新到最新版本 - 它们会随着时间的推移解决很多问题.
更新令牌
这是我们处理续订调用的代码(c#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;
}
Run Code Online (Sandbox Code Playgroud)
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文档,当你获得令牌时,你得到令牌到期时的秒数.文档将响应格式列为:
access_token=USER_ACESS_TOKEN&expires=NUMBER_OF_SECONDS_UNTIL_TOKEN_EXPIRES
Run Code Online (Sandbox Code Playgroud)
这得到了Ouath 2的RFC草案的支持,该草案称响应应该包含到期时间.
不幸的是,它直接由规定的C#SDK文档矛盾在这里说
如果没有向Facebook发出请求,则无法确定访问令牌是否过期.因此,您必须始终假设在向Facebook发出请求时,访问令牌可能已过期.
这不是真的.如果查看c#SDK源代码,sdk为OAuth响应创建的对象显式包含(不幸的是作为私有变量)以下代码
/// <summary>
/// Date and Time when the access token expires.
/// </summary>
private readonly DateTime _expires;
Run Code Online (Sandbox Code Playgroud)
所以它有数据,但由于某种原因不暴露它(至少在那里,我没有进一步看).我要说要么更多地挖掘库,看看它是否暴露在某个地方,在github上分叉和修补它(我相信这是一行更改),或者使用反射来读取你自己代码中的私有变量.
简短的回答:也许吧.如果您知道令牌已过期,您可以在请求之前明显地获得新令牌.
如果你没有,那么你可以,但你需要处理你的请求失败.从理论上讲,这并不意味着您需要处理异常,只需查看http状态代码(400个中的一个可能是403禁止的)但是C#的webrequest方法将非200状态c作为引发异常的事件进行交互.由于API使用此机制进行调用,因此只有在失败时才会出现异常.
当然,在你处理异常之后.
一旦发生这种情况,异步,您将获得一个新的身份验证令牌.因此,您可以在捕获异常后等待一段时间,检查是否为该用户获取了新令牌,如果是,则重试.如果继续等待和检查.确保您有最大重试次数和最长等待时间.拉动数据库以检查更改是有点低效的,因此您可能希望选择仔细检查更改的时间间隔,并可能使其以指数方式退回.
另一个更有效的(对于单个服务器),但是复杂的方式是让系统通过auth令牌获取回调引发事件并让重试逻辑监听这些事件.
当您的代码因令牌过期而获得异常时,在catch块中创建一个函数,该函数将重做请求,然后将其作为事件侦听器添加到auth事件中.让函数检查事件是否为请求事件的用户提供了新的身份验证令牌,如果是,请发出请求.再次,记住要有最大重试次数.
实际上不可能使用async/await或类似的东西等待您的新令牌的请求完成.问题是,刷新API令牌并不是您可以等待响应的请求,它实际上会触发最终导致单独获取请求的内容
请注意,尽管上图是针对用户首次登录时的情况,但大致在失败的呼叫中会发生相同的序列,但它会从重定向开始.