我目前正试图将最新的Facebook php sdk整合到Phalcon项目中,但我没有太多运气。
我可以让SDK在独立项目中工作,但是当集成到Phalcon项目(作为服务或直接在Controller中)时,完全相同的代码会失败。
问题似乎是facebook重定向助手创建了一个"状态"附加到loginUrl然后存储在会话中的属性。当用户在登录后重定向回我的站点时,它会根据查询字符串值检查此属性。只有通过redirectHelpers getLoginUrl()方法显示登录URL时,才会生成并存储state属性。不知何故,当我在Phalcon中集成它时,会话变量和$ _GET参数似乎永远不会匹配。有效的简单例子如下
// lots of requires
Facebook\FacebookSession::setDefaultApplication($appId,$secret);
$helper = new Facebook\FacebookRedirectLoginHelper('http://'.$_SERVER['HTTP_HOST'] .'/');
// see if a existing session exists
if ( isset( $_SESSION ) && isset( $_SESSION['fb_token'] ) ) {
// create new session from saved access_token
$session = new FacebookSession( $_SESSION['fb_token'] );
// validate the access_token to make sure it's still valid
try {
if ( !$session->validate() ) {
$session = null;
}
} catch ( Exception $e ) {
// catch any exceptions
$session = null;
}
} // end if isset($_SESSION)
if ( !isset( $session ) || $session === null ) {
// no session exists
try {
$session = $helper->getSessionFromRedirect();
} catch( FacebookRequestException $ex ) {
// When Facebook returns an error
// handle this better in production code
print_r( $ex );
} catch( Exception $ex ) {
// When validation fails or other local issues
// handle this better in production code
print_r( $ex );
}
}
// see if we have a session
if ( isset( $session ) ) {
// save the session
$_SESSION['fb_token'] = $session->getToken();
// create a session using saved token or the new one we generated at login
$session = new FacebookSession( $session->getToken() );
// graph api request for user data
$request = new FacebookRequest( $session, 'GET', '/me' );
$response = $request->execute();
// get response
$graphObject = $response->getGraphObject()->asArray();
// print profile data
echo '<pre>' . print_r( $graphObject, 1 ) . '</pre>';
// print logout url using session and redirect_uri (logout.php page should destroy the session)
echo '<a href="' . $helper->getLogoutUrl( $session, 'http://yourwebsite.com/app/logout.php' ) . '">Logout</a>';
} else {
// show login url
echo '<a href="' . $helper->getLoginUrl( array( 'email', 'user_friends' ) ) . '">Login</a>'; // this line would generate a new state
}
当我尝试在phalcon项目的控制器中使用这个完全相同的代码时(或通过在$ di中设置&#34; $ me&#34; up),状态检查总是失败,即使我是没有生成新的登录URL。唯一的另一个区别是,在简单的项目中,我需要使用require_once的所有facebook文件,但在我使用的Phalcon项目中
$loader->registerNamespaces(
array(
"Facebook" => __DIR__ . '/../../vendor/facebook/php-sdk-v4/src/Facebook/'
)
);
但将其替换为要求并不会产生影响。
有人有任何线索吗?
答案 0 :(得分:0)
我通过使用registerClasses而不是registerNamespaces来使用它 - 但是使用v3.2.x而不是v4。
$loader->regeisterNamespaces( /* Projects' classes */ )
->registerClasses(array(
'Facebook' => __DIR__ . '/../../vendor/facebook/php-sdk/src/facebook.php'
))
->register();
ps。:我使用composer加载FacebookSDK,所以我的路径与你的路径不同。
然后我在Controller普通中使用它而不使用$ di,
protected function getFacebook()
{
if (!$this->facebook) {
$this->facebook = new Facebook(array(
'appId' => $this->config->social->facebook->appId,
'secret' => $this->config->social->facebook->secret,
'fileUpload' => false,
'allowSignedRequest' => false,
));
}
return $this->facebook;
}
答案 1 :(得分:0)
我已经解决了这个问题。问题是浏览器也自动向/favicon.ico发出请求,因为我没有favicon.ico,然后再次呈现默认的indexAction,因此导致getLoginUrl()方法火再次产生一个新的状态。简单的解决方法是创建一个favicon,或者为不存在的文件定义错误处理路径(我最初只使用phalcon开发工具中的样板)