我正在创建一个Facebook画布应用程序,虽然身份验证似乎在主应用程序视图页面上正常工作(从http://app.mycanvasurl.com加载),但当我尝试在应用程序中添加其他页面时,它不会工作(由于某种原因,访问令牌未正确返回,因此页面返回和OAuth异常[null访问令牌]并重新指向主应用程序页面)。
截至目前,我正在相对引用URL(a href =“/ directory /”),但我也试过了一个绝对的(http://apps.facebook.com/my-app/directory/)当您在浏览器中导航到该URL时,它会工作,但当您单击应用程序中的链接时,没有任何反应(我假设这是因为它在iframe中,但即使尝试设置top.location.href onclick也是如此无法改变状态。)
这是我构建的身份验证类(无论如何都是主要方法)
function __construct() {
$this->API = new Network(false);
$this->DB = new Database();
session_start();
$this->code = $_REQUEST['code'];
if (empty($this->code)) $this->doAuth(); // Authorize User & Create New Session Access Token
if ($_REQUEST['state'] == $_SESSION['state'] || 1==1) { // Everything is alright, go ahead and grab the User object
$tokens = array('{APP_ID}','{APP_URL}','{APP_SECRET}','{REQ_CODE}');
$tokenReplacements = array(self::$APP['id'], self::$APP['url'], self::$APP['secret'], $this->code);
parse_str($this->APIRequest('access_token', $tokens, $tokenReplacements, false), $responseParams);
$this->accessToken = $responseParams['access_token'];
$this->User = $this->APIRequest('graph_me', array('{ACCESS_TOKEN}'), array($this->accessToken));
if (is_object($this->User)) {
$found = $this->DB->fetch('SELECT * FROM user WHERE `fb_id` = "'.$this->User->username.'"');
if (!$found) $this->addUser();
}
}
}
protected function APIRequest($url, Array $tokens, Array $replacements, $decode = true) {
$this->API = (is_object($this->API) && get_class($this->API) == 'Network') ? $this->API : new Network(false);
if (self::$URL[$url] && count($tokens) == count($replacements)) {
$requestURL = str_replace($tokens, $replacements, self::$URL[$url]);
$this->API->newConn($requestURL);
return ($decode == true) ? json_decode($this->API->Execute()) : $this->API->Execute();
} else {
return false;
}
}
protected function doAuth() {
$_SESSION['state'] = md5(uniqid(mt_rand(),TRUE)); // CSRF Protection
$oauthURL = str_replace(array('{APP_ID}','{APP_URL}','{SESS_STATE}'), array(self::$APP['id'], urlencode(self::$APP['url']), $_SESSION['state']), self::$URL['oauth']);
die('<script>top.location.href="'.$oauthURL.'"</script>');
}
还有一件事:如果你在构造函数中注意到,有一个1 == 1来覆盖条件CSRF保护检查。这是因为删除它会导致应用程序进入无限重定向循环(由于某种原因,这些值永远不会匹配,我无法弄清楚原因)