Я создаю приложение на холсте Facebook, и хотя кажется, что аутентификация работает правильно на главной странице просмотра приложения (загружается из http://app.mycanvasurl.com),, когда я пытаюсь добавить другие страницы в приложение, оно не работать (по какой-то причине токен доступа не возвращается правильно, поэтому страница возвращается и OAuth-исключение [нулевой токен доступа] и перенаправляет обратно на главную страницу приложения).
На данный момент я ссылаюсь на 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. Это связано с тем, что его удаление приводит к тому, что приложение входит в бесконечный цикл перенаправления (по какой-то причине эти значения никогда не совпадают, и я не могу понять, почему)