我知道这个问题是另一个问题的重复,但是在搜索Google和Stack Overflow之后,我仍然没有找到解决方案。Facebook API - 永久数据中缺少必需的参数“状态”
我有一些调用Facebook API的登录URL的代码。但是,我以一种间接的方式来做这件事。基本上这里是服务器流量:
- 客户选择登录与FB到App
- 客户网站(A)发送HTTP GET请求到中间网站(B)
- 网站B返回登录URL B关于网站它包括2个回调:到FB与FB-> getLoginUrl(生成的登录URL)和回调网站A.
- 网站甲重定向到登录在其重定向到登录页面上FB
- 用户登录网站B页并授权FB网站上的应用程序
- FB重定向到获取访问码的网站B上的回调。作为$ _GET变量
- 网站上使用访问令牌,因为它希望
所以很复杂,我只包括流可能使回答
PHP 网站代码:
if (!isset($_GET['code'])) {
$callback = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$request_url = "http://embocorp.com/factory/api.php/facebook/login?callback=".$callback;
header("Location: ".implode(json_decode(callAPI("GET", $request_url), true)['body']['data']));
} else {
echo $_GET['code'];
}
网站B代码: api.php
if (!session_id()) {
session_start();
}
require_once("vendor/autoload.php");
$method = $_SERVER['REQUEST_METHOD'];
$request = explode('/', trim($_SERVER['PATH_INFO'],'/'));
$input = $_SERVER['PATH_INFO'];
$table = array_shift($request);
$key = array_shift($request);
parse_str($_SERVER['QUERY_STRING'], $query_array);
$callback = "http://embocorp.com/factory/api.php/facebook/callback?call=";
function returnData($data, $options = "") {
$response = [
"data"=>$data
];
return json_encode($response, $options);
}
function getFacebookConnection($appid, $appsecret) {
return new Facebook\Facebook(['app_id' => $appid,'app_secret' => $appsecret,'default_graph_version' => 'v2.5', 'persistent_data_handler'=>'session']);
}
function facebookHandleRequest($request, $connection, $details = null) {
switch($request) {
case "login":
$callback_url = $GLOBALS["callback"].$GLOBALS['query_array']['callback'];
echo returnData("http://embocorp.com/factory/login.php?fb=".getFacebookLoginURL($connection, $callback_url), JSON_UNESCAPED_SLASHES);
break;
case "callback":
if (!empty($GLOBALS["query_array"])) {
foreach ($_COOKIE as $k=>$v) {
if(strpos($k, "FBRLH_")!==FALSE) {
$_SESSION[$k]=$v;
}
}
$access = getFacebookAccessCode($connection);
$called = $GLOBALS['query_array']['called'];
header("location: ".$called."?code=".$access);
} else {
echo returnError(400, "Bad Request, missing authorization");
}
break;
case "me":
if (!empty($GLOBALS["query_array"]) && array_key_exists("accessToken", $GLOBALS["query_array"]) == true) {
$response = $connection->sendRequest('GET', '/me', [], $GLOBALS["query_array"]["accessToken"], 'eTag', 'v2.2');
$user = $response->getGraphUser();
echo returnData($user);
} else {
echo returnError(400, "Bad Request, missing authorization");
}
break;
default:
echo returnError(404, "Request URI Not Found");
break;
}
}
function getFacebookLoginURL($connection, $callback_url) {
$helper = $connection->getRedirectLoginHelper();
$permissions = ['manage_pages', 'publish_pages', 'read_insights'];
$loginUrl = $helper->getLoginUrl($callback_url, $permissions);
foreach ($_SESSION as $k=>$v) {
if(strpos($k, "FBRLH_")!==FALSE) {
if(setcookie($k, $v)) {
$_COOKIE[$k]=$v;
}
}
}
return $loginUrl;
}
function getFacebookAccessCode($fb){
if (!session_id()) {
$accessToken = $_SESSION['facebook_access_token'];
return $accessToken;
} else {
$helper = $fb->getRedirectLoginHelper();
try {
$accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
if (isset($accessToken)) {
$_SESSION['facebook_access_token'] = (string) $accessToken;
return (string) $accessToken;
} else {
return false;
}
}
}
switch ($table) {
case "facebook":
$fb = getFacebookConnection($appid, $appsecret);
facebookHandleRequest($key, $fb);
break;
case "twitter":
echo "no";
break;
default:
exit();
break;
}
session_write_close();
?>
的login.php
if (!session_id()) {
session_start();
}
if (isset($_GET['fb'])) {
$redirect = str_replace("fb=", "", $_SERVER['QUERY_STRING']);
header("Location: ".$redirect);
} else {
echo "ni";
}
再次感谢您的帮助,这已经让我疯狂了72小时。
你在哪里执行交换访问令牌代码的步骤?由于您在域B下创建了登录URL,因此您必须在B上执行此操作,因为状态值存储在域B的会话中。 – CBroe
我在域B上执行它。Login.php转到facebook,然后转到返回api.php交换访问令牌的代码。 –
然后检查您的会话(在B上)是否正常工作 - 您是否在前后获得相同的会话ID? – CBroe