Facebook身份验证实施

时间:2011-07-25 14:26:12

标签: php authentication facebook-graph-api facebook-php-sdk facebook-javascript-sdk

我正在开发一个完全使用facebook身份验证的项目(不存在自定义身份验证实现)。 Project使用PHP进行服务器端脚本编写。我四处寻找实现快速安全的身份验证机制,但我找不到有关此主题的任何详细说明。 Facebook的文档很薄弱,只提供基本信息。

哪种认证方法合适?有一个Javascript SDK和PHP SDK。据我所知,我必须使用Javascript SDK进行登录,然后使用PHP SDK我将检查我的数据库以验证凭据。但是使用带有PHP SDK的Graph API很慢。有没有更好的方法来验证会话?

我是否需要在每次请求时检查会话服务器端(PHP-SDK)?

7 个答案:

答案 0 :(得分:9)

与我见过的任何其他方法相比,我最终为我的应用做的事情非常简单且相对较快。

  1. 检查signed_request(如果存在),如果存在则解析它。如果没有,请在PHP
  2. 中将$ login标志设置为1
  3. 我检查用户的会话/ cookie以查看该用户之前是否已经过该应用程序的身份验证(稍后会再回来。如果它是空的,请将$ login设置为1。
  4. 如果登录标志设置为1,则将用户发送到安装URL。
  5. 用户安装应用程序并将其发送到连接器页面。此页面用于获取access_token并为用户生成会话/ cookie。这意味着您可能不需要在用户会话的生命周期内检查此access_token的有效性。 offline_access也创造了新的机会。您也可以将access_token存储在数据库中。
  6. 每当您拨打电话到Facebook时,请检查例外情况,如果您遇到身份验证例外,请清除用户的会话和Cookie。下次它将强制他们更新access_token,即使此过程对用户不可见。
  7. 我已在我的应用上完成此操作,在大多数情况下意味着我不必向FB查询以查看access_token的有效性,也不必在每个页面视图上不断获取它。我们的目标是减少应用程序的延迟,但Facebook是延迟的最大来源,这样做可以大大减少。

答案 1 :(得分:1)

回答我自己的问题:

我使用Javascript SDK检查facebook身份验证是否可用。

  • 如果fb身份验证没问题并且我的应用程序未经过身份验证,我会向用户提供预先填写的facebook注册表单。
  • 如果fb身份验证不正常,我会提供Facebook登录按钮。

注册插件授权我的应用程序,我调用我的fblogin.php使用PHP SDK检查此信息。当PHP SDK验证授权时,它会将此信息存储在会话变量中。因此,无需在每个请求中检查fb身份验证。

登录按钮与注册插件相同。这些方法共享相同的服务器端功能,但它们的表示形式不同。

为了捕获facebook注销状态,我使用Javascript SDK在每个请求上验证facebook身份验证。如果用户注销,我的js代码调用fblogout.php并销毁当前会话。这种方法存在缺陷。如果用户没有明确地从我的网站注销,攻击者可以代表用户做任何事情,只能在同一台机器上禁用js。

我找不到具有快速响应时间的更好解决方案。

答案 2 :(得分:1)

您可以使用其中一个或两个。

您可以使用PHP SDK生成相关的URL以发送给人们。只是在链接上搞砸了。 或者您可以使用Javascript来制作Facebook默认登录按钮。

之后,您可以使用其中一个来维护和验证会话。

我通常使用PHP来使用oAuth密钥进行繁琐的工作,并使用JavaScript SDK制作漂亮的Facebook按钮和一些不那么重要的会话监控图形调用。

任何涉及任何繁重或多次图形调用的内容都会推送到PHP。

但是有灵活性可以做你想做的事。您不必使用JavaScript SDK进行登录。

如果你想验证每个页面的加载,这取决于你。

我倾向于使用Javascript SDK来处理它,如果会话已经死了,我会喜欢Berk。将页面重定向调用到注销脚本。

答案 3 :(得分:1)

从最新版本开始,PHP和JS SDK现在都能够访问相同的用户会话(使用JS PHP登录[而不必同时执行这两者])。查看this blog post以获取更详细的说明和示例。

如果您担心安全问题,也许您可​​以将会话Cookie设置为session_set_cookie_params()更快过期。

答案 4 :(得分:1)

我认为您不需要实施SDK。

1,您需要获得用户的许可才能访问他/她的数据。所以你需要将它们重定向到Facebook。这是PHP中的少量(3-5)代码行。

https://graph.facebook.com/oauth/authorize?
client_id=YOUR_APP_ID&scope=email&redirect_uri=APP_URL 

2,当用户返回您的网站时,请使用$ _GET ['code']

http://YOUR_URL?code=A_CODE_GENERATED_BY_SERVER

3,您必须通过Facebook获取请求解码此代码,并获取access_token。

https://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

3,在你拥有access_token之后,只需要经常运行一个/ me?access_token GET请求,检查用户是否还在那里。

4,您可以存储Facebook ID。

我认为这是最快捷的方式。据我所知,javascript sdk使用弹出窗口,大多数浏览器都会阻止它。

此流程在此处详细说明:http://developers.facebook.com/docs/authentication/

答案 5 :(得分:1)

首先,只是提醒您,您不仅需要保存access_token,而且理想情况下,您希望将用户的facebook uid与访问令牌一起保存。这通常是因为您需要在API调用中包含uid和访问令牌。

其次,来自Facebook Documentation

  

注意:如果应用程序未请求offline_access权限,   访问令牌是有时间限制的。时间限制的访问令牌也得到了   当用户退出Facebook时失效。如果申请有   从用户获得了offline_access权限,访问令牌   没有到期日。但是无论何时用户都会失效   更改他/她的密码。

第三,拥有access_token和uid的目的是执行API调用,对吧?从那里开始。 进行身份验证,如果只有access_token(以某种方式)变为无效。如何检查其是否有效呢?好吧,您可以使用cURL(Reference)或Proxy Library(但您可能需要稍微修改它,因为它最初是为CI编写的),以便将API调用作为验证过程。示例(*叹气,使用我的代理库)...

// Suppose we are try to publish a status from our fb app
// $access_token hold the user access_token, which you saved into your database
// $uid hold the user facebook uid, which you saved into your database
$proxy = new Proxy;
// This is equal with perform regular HTTP POST request with cURL
$api_call = $proxy->http('post','https://graph.facebook.com/'.$uid.'/feed', array('access_token' => $access_token,'message' => 'foo'));

// Now we can validate...
// If the API success, it will be returned a post id, with json format
// if not, it will be outputing json like...
// "{"error":{"type":"OAuthException","message":"Invalid OAuth access token."}}"
// so...
$result = (array) json_decode($api_call);
if(array_key_exists('error', $result))
{
    // Here you can perform an oAuth authentification, to get fresh access_token and update your database
    // ...
    // After it done, process the previous api call with valid access_token
    $proxy->http('post','https://graph.facebook.com/'.$uid.'/feed', array('access_token' => $access_token,'message' => 'foo'));
}

答案 6 :(得分:1)

Facebook Connect文档相当有限。它并没有真正告诉你它在做什么,只是如何做到这一点。我个人不使用任何一个SDK。我为我的开发项目构建了自己的框架。

这两个SDK以及教程中的JavaScript都是IMO,已经过时了。

如果你想坚持使用其中一个FB SDK,这是我的建议。仅当您的Graph API查询等通过Ajax发送到PHP后端时才使用JS SDK。否则坚持使用PHP SDK。

<强>简介

Facebook使用oAuth v2。他们描述了两种不同的流程方法......服务器端和客户端。这将与针对oAuth v2服务进行身份验证的任何其他应用程序实现相同。他们都做同样的事情。唯一的区别可能是您可以使用'code'作为request_type来获取将来获取令牌的授权码。

<强>验证

就FB Connect而言,您的脚本需要确保您在需要身份验证时拥有身份验证令牌或身份验证代码。如果你没有,那么你需要得到它。您可以使用auth代码或令牌作为FB按钮显示(登录或注销)的条件。

将用户重定向到oAuth以进行身份​​验证。 Facebook将他们的oAuth实现捆绑在他们的对话API中。有关oAuth对话的更多信息,请访问:http://developers.facebook.com/docs/reference/dialogs/oauth/

您可以将可选的state参数用于CSRF保护等内容。它在进程后保留它的值,并以回调作为GET参数发送。

应用互动

基本上你会像往常一样编写你的应用程序。差异将是:

  1. 您的用户数据库不再存储密码,只存储FB UID。此外,根据FB Dev ToS,您实际上无法存储任何用户信息。如果要存储用户信息,则需要从用户处获取该信息。您可以使用FB信息为他们填充此信息,您只需要他们提交即可。
  2. 您的注册方法不再有表单前端发布到它。当经过身份验证的用户在数据库中没有条目时,将调用它。
  3. API互动

    如果您使用代码而不是令牌,则需要通过发送代码来请求令牌。这是通过Graph API oauth完成的。除了他们的身份验证教程之外,本部分没有记录。 http://developers.facebook.com/docs/authentication/

    使用您的访问令牌,无论您使用哪种方法获取它。您现在可以根据需要查询Graph API。这将返回一个JSON编码对象。

    <强>结论

    就快速安全的实施而言,Facebook PHP SDK可以胜任。它处理我在这里介绍的所有内容,包括CSRF。如何学习它,我还没有找到合适的文档。一切都是旧的,或者作者并不真正知道,并且正在脱离其他教程。

    你最好的办法是深入挖掘这些图书馆并弄清楚它是如何运作的。做一些反复试验,试验。

    我学到的方法是为自己编写自己的框架。我建议你这样做。如果您愿意,可以扩展Facebook SDK类。它确实有限,但它可以满足您的所有需求。我接受了最常用的API调用并将它们放入。我现在有一个非常快速和简单的最终结果,它来自我的库。