Facebook API - Required param "state" missing from persistent data - php

I know that this question is a duplicate of another, however after searching Google and Stack Overflow, I have still yet to find a solution.
I have some code which calls the Facebook API for a login URL. However, I am doing it in a somewhat indirect way. Basically here is the server flow:
Client chooses to login to app with FB
Client website (A) sends HTTP GET request to intermediate website (B)
Website B returns login URL on website B which includes 2 callbacks: a login URL to FB generated with fb->getLoginUrl() and a callback to website A.
Website A redirects to login page on Website B which redirects to login page on FB
User logs in and grants permissions to app on FB website
FB redirects to callback on website B which gets the access code.
Website B redirects to Website A callback passing the access code as a $_GET variable
Website A uses the access token as it wishes
So very complicated and I only include the flow to possibly make answering this question and understanding the code in PHP easier.
PHP
Website A Code:
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'];
}
Website B Code:
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";
}
Again, thank you for any help, this has been driving me crazy for 72 hours now.

Just add,
if (!session_id()) {
session_start();
}
in start both file.

Related

Facebook login php sdk - problem on mobile devices - empty headers [website app]

I have a little problem with my integration with Facebook PHP SDK on my website. On desktop everything works fine. When try to register account using fb-login button on mobile devices despite the successful redirection from the facebook website to my website, it receives an empty response.
I don't know where is the main problem, session, redirects policy, cookie problem?
The problem does not exist when accounts are merged and connected - so login function works on mobile, just creating account and connecting new ids.
I note that everything works fine on the desktop version
my config
Facebook PHP SDK: 5.6.2
Graph API: v14.0
$config = array_merge([
'app_id' => getenv(static::APP_ID_ENV_NAME),
'app_secret' => getenv(static::APP_SECRET_ENV_NAME),
'default_graph_version' => static::DEFAULT_GRAPH_VERSION,
'enable_beta_mode' => false,
'http_client_handler' => null,
'persistent_data_handler' => 'memory',
'pseudo_random_string_generator' => null,
'url_detection_handler' => null,
], $config);
You can see the code implementations below
public function _facebook_account($action = null){
$isLogged = $this->getCustomer()->isAuthenticated();
$fb = FacebookAPIHelper::getInstance()->getAPI($this->getContext());
$redirectUrl = null;
if (!empty($_POST['secret_code']))
{
$code = $_POST['secret_code'];
}
if (!$isLogged) {
if ($action == FacebookAPI::ACTION_LOGIN || $action == FacebookAPI::ACTION_REGISTER){
$redirectUrl = '/customer/login_with_facebook/' . $action;
}
}
else{
if ($action == FacebookAPI::ACTION_MERGE) {
$redirectUrl = '/customer/merge_with_facebook';
}
else {
$this->redirectTo('customer,profile');
}
}
if (!is_null($redirectUrl)) {
$url = $fb->getLoginUrl($this->getRouter()->getHost(null, true) . $redirectUrl, isset($code) ? $code : null);
header("Location: $url");
}
else {
$this->redirectTo('');
}
}
2
try {
$facebookProfileData = FacebookLoginHelper::getFacebookProfileData($this->getContext());
if ($facebookProfileData) {
$customer = FacebookLoginHelper::findOrCreateCustomerByFacebookProfileData($facebookProfileData);
} else {
$this->addMessageForNextRequest('`facebook_login.error_fetch_user_data`');
$this->redirectTo('customer,login');
}
if (is_null($customer)) {
$customer = CustomerBase::getCustomerFromFacebookProfileData($facebookProfileData);
if (Module::moduleInstalled('referer')) {
if ($this->hasCookie(RefererSettings::COOKIE_NAME)) {
$referer = $this->getCookie(RefererSettings::COOKIE_NAME);
$customer->referer = $referer;
}
}
$this->view->customer = $customer;
$this->renderAction('confirm_customer_data.tpl');
}
3
public function _login_with_facebook($action)
{
$customer = null;
$oldCustomer = $this->getCustomer();
$isLogged = $oldCustomer->isAuthenticated();
$facebookLoginNotInstalled = Module::moduleInstalled('facebook_login') == false;
if ($isLogged) {
$this->redirectTo('customer,profile');
return;
}
if ($facebookLoginNotInstalled) {
$this->redirectTo('customer,login');
return;
}
try {
$facebookProfileData = FacebookLoginHelper::getFacebookProfileData($this->getContext());
if ($facebookProfileData) {
$customer = FacebookLoginHelper::findOrCreateCustomerByFacebookProfileData($facebookProfileData);
} else {
$this->addMessageForNextRequest('`facebook_login.error_fetch_user_data`');
$this->redirectTo('customer,login');
}
if (is_null($customer)) {
$customer = CustomerBase::getCustomerFromFacebookProfileData($facebookProfileData);
if (Module::moduleInstalled('referer')) {
if ($this->hasCookie(RefererSettings::COOKIE_NAME)) {
$referer = $this->getCookie(RefererSettings::COOKIE_NAME);
$customer->referer = $referer;
}
}
$this->view->customer = $customer;
$this->renderAction('confirm_customer_data.tpl');

Session Dying Right After Calling Auth::login()

Stackoverflow community! We've been struggling with this issue for a while now. We're attempting to upgrade our Laravel v4 site to Laravel v7. So far, it's been fine. When we use our login function, it properly authorizes the user, but upon redirect, the session gets killed. We've checked it over and over again, but we simply cannot find anything that could be the cause of the issue. Here is the suspect function:
public function loginv2()
{
if (Auth::check()) {
return Redirect::action('FrontController#showWelcome')->withMessage("Already logged in.");
}
if (!Auth::check() && !isset($_GET['token']))
{
$_SESSION['redirect'] = "https://zjxartcc.org";
header("Location: https://login.vatusa.net/uls/v2/login?fac=ZJX");
exit;
}
$token = $_GET['token'];
$parts = explode('.', $token);
$token = $this->base64url_decode($parts[1]);
$jwk = json_decode('{"alg":"HS256","use":"sig","kty":"oct","k":"..."}', true);
$algorithms = ['HS256' => 'sha256', 'HS384' => 'sha384', 'HS512' => 'sha512'];
if (!isset($algorithms[$jwk['alg']])) {
return Redirect::action('FrontController#showWelcome')->withMessage("Invalid Operation");
}
$sig = $this->base64url_encode(hash_hmac($algorithms[$jwk['alg']], "$parts[0].$parts[1]", $this->base64url_decode($jwk['k']), true));
if($sig == $parts[2]) {
$token = json_decode($token, true);
if($token['iss'] != 'VATUSA') {
return Redirect::action('FrontController#showWelcome')->withMessage("Not issued from VATUSA");
}
if($token['aud'] != 'ZJX') {
return Redirect::action('FrontController#showWelcome')->withMessage("Not issued for ZJX");
}
$client = new GuzzleHttp\Client();
$url = "https://login.vatusa.net/uls/v2/info?token={$parts[1]}";
$result = $client->get($url);
$res = json_decode($result->getBody()->__toString(), true);
$userstatuscheck = User::find($res['cid']);
if($userstatuscheck) {
if($userstatuscheck->status == 1) {
return Redirect::action('FrontController#showWelcome')->withMessage("You are not an active controller, and cannot login.");
} else {
Auth::login($userstatuscheck, true);
require("/home2/zjxartcc/public_html/forum/smf_2_api.php");
smfapi_login($userstatuscheck->id);
setcookie("ids_loggedin", $res['cid'], 0, "", ".zjxartcc.org");
$_SESSION['loggedin'] = $res['cid'];
}
} else {
return Redirect::action('FrontController#showWelcome')->withMessage("No user matching your information on the roster.");
}
//update email records and rating
$forum = SMFMember::find($res['cid']);
$forum->email_address = $res['email'];
$forum->save();
$member = User::find($res['cid']);
$member->rating_id = $res['intRating'];
$member->email = $res['email'];
$member->save();
return Redirect::action('FrontController#showWelcome')->withMessage('You have been logged in!');
} else {
return Redirect::action('FrontController#showWelcome')->withMessage("Bad Signature");
}
}
All help and suggestions are greatly appreciated! Thank you!

Google Drive API - Call to a member function on a non-object when trying to update a file

I am trying to access and update a file in my Google Drive with PHP. Everything goes fine until I try to call $file_to_update->setTitle("NEW TITLE").
I can download the file's metadata, but I can't update anything.
require_once 'google-api-php-client/Google_Client.php';
require_once 'google-api-php-client/contrib/Google_DriveService.php';
$client = new Google_Client();
// Get your credentials from the console
$client->setClientId('');
$client->setClientSecret('');
$client->setRedirectUri('');
$client->setScopes(array(''));
$service = new Google_DriveService($client);
$authUrl = $client->createAuthUrl();
//Request authorization
print "Please visit:\n$authUrl\n\n";
print "Please enter the auth code:\n";
$authCode = trim(fgets(STDIN));
// Exchange authorization code for access token
$accessToken = $client->authenticate($authCode);
$client->setAccessToken($accessToken);
retrieveAllFiles($service);
function retrieveAllFiles($service) {
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$fileIDs = array();
$file = ($files[items]);
foreach($file as $f){
array_push($fileIDs, $f["id"]);
print $f["id"]."\n";
}
$str = $fileIDs[1];
$file_to_update = $service->files->get($str);
$file_to_update->setTitle("NEW TITLE");
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
return $result;
}
Your call to $service->files->get($str) is not returning object.
if you check at function:
public function get($fileId, $optParams = array()) {
$params = array('fileId' => $fileId);
$params = array_merge($params, $optParams);
$data = $this->__call('get', array($params));
if ($this->useObjects()) {
return new Google_DriveFile($data);
} else {
return $data;
}
}
It checks if you want to work with objects, or not:
$this->useObjects()
You need to configure 'use_objects' to 'true' in your api config.php file, it is set to 'false' by default.
'use_objects' => false,

JSON PHP Can't call value from Steam URL

I'm trying to create a website with Steam's login, but when I try to call a value from JSON, it doesn't work. Everything works in the source code, except for getting the JSON value. I've even tried printing the steam ID, so I know that ID works. The URL works also.
Here's my source code:
<?php
require 'openid.php';
try {
$openid = new LightOpenID('workinganonymouswebsite.com');
if (!$openid->mode) {
$openid->identity = 'http://steamcommunity.com/openid';
header('Location: ' . $openid->authUrl());
} elseif ($openid->mode == 'cancel') {
echo 'User has canceled authentication!';
} else {
$steamurl = ($openid->validate() ? $openid->identity . '' : 'error');
if ($steamurl == 'error') {
print "There was an error signing in.";
} else {
$id = end(explode('/', $steamurl));
$jsonurl = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=XXXXXXXXXXXXXXXXXX&steamids=" . $id . "&format=json";
$json = file_get_contents($jsonurl, 0, null, null);
$json_output = json_decode($json);
echo $json_output['players']['personaname'];
}
}
} catch (ErrorException $e) {
echo $e->getMessage();
}
?>
Here's the JSON on the website.
{
"response": {
"players": [
{
"steamid": "76561198049205920",
"communityvisibilitystate": 3,
"profilestate": 1,
"personaname": "baseman101",
"lastlogoff": 1357603378,
"profileurl": "http://steamcommunity.com/id/baseman101/",
"avatar": "http://media.steampowered.com/steamcommunity/public/images/avatars/24/24bb7c0505db7efe1f1a602d09a5ea412e0ab4bd.jpg",
"avatarmedium": "http://media.steampowered.com/steamcommunity/public/images/avatars/24/24bb7c0505db7efe1f1a602d09a5ea412e0ab4bd_medium.jpg",
"avatarfull": "http://media.steampowered.com/steamcommunity/public/images/avatars/24/24bb7c0505db7efe1f1a602d09a5ea412e0ab4bd_full.jpg",
"personastate": 1,
"primaryclanid": "103582791429521408",
"timecreated": 1316469294,
"loccountrycode": "US",
"locstatecode": "VA",
"loccityid": 3918
}
]
}
}
I've tried googling everything. I'm sorry if there is something I missed.
Thanks for all of your help. I basically put the JSON code in a variable, retrieving it from the Steam website. This is the best solution and I'm sticking to it.
<?php
require 'openid.php';
try {
$openid = new LightOpenID('blah.com');
if (!$openid->mode) {
$openid->identity = 'http://steamcommunity.com/openid';
header('Location: ' . $openid->authUrl());
} elseif ($openid->mode == 'cancel') {
echo 'User has canceled authentication!';
} else {
$steamurl = ($openid->validate() ? $openid->identity . '' : 'error');
if ($steamurl == 'error') {
print "There was an error signing in.";
} else {
$id = end(explode('/', $steamurl));
$context = stream_context_create(array('http' => array('header'=>'Connection: close\r\n')));
$json_source = file_get_contents("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=XXXXXXXXXXXXXXXXXXXXXXXX&steamids=" . $id . "&format=json",false,$context);
$json_output = json_decode($json_source,true);
$json_output->response->players[0]->personaname;
echo $json_output["response"]["players"][0]["personaname"];
}
}
} catch (ErrorException $e) {
echo $e->getMessage();
}
?>
Thank you, Passerby and hakre for the help.
In the future, I have to create cookies, and all of the easy stuff. I'm actually starting that right now.

CodeIgniter Facebook API getuser always 0

I know this is a duplicate, however, I've tried pretty much everything suggested in the other questions.
I'm currently getting a redirect loop because getUser is always returning 0, even after approving the app.
Code:
public function auth() {
$user = $this->facebook->getUser();
if ($user) {
$user = $this->facebook->api('/me');
if (!$this->Users->getByID($user["id"])) {
$this->data->needsRegister = true;
} else {
$toSetInSessions = new stdClass();
$toSetInSessions->authed = 1;
$dbUser = $this->Users->getByID($user["id"]);
foreach ($dbUser as $key => $value) {
$toSetInSessions->user->$key = $value;
}
$this->session->set_userdata($toSetInSessions);
redirect("/");
}
} else {
$params = array('scope' => 'email,read_friendlists');
if ($_SERVER['HTTP_USER_AGENT'] != "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)") {
redirect($this->facebook->getLoginUrl($params));
}
}
$this->load->view('header', $this->data);
$this->load->view('auth', $this->data);
$this->load->view('footer', $this->data);
}
Here is the screenshot of my settings page for this App.
https://dl.dropbox.com/u/6647629/facebookapp.png
Sometimes it does work, but most of the time it doesn't.
Found the solution here: http://www.galalaly.me/index.php/2012/04/using-facebook-php-sdk-3-with-codeigniter-2-1/
Had to add:
parse_str($_SERVER['QUERY_STRING'], $_REQUEST);

Categories