FB API inserting user_id that belongs to Open User account - php

This is easily the most bizarre problem that I've ever run into while using the FB api. Maybe I'm just too much of a n00b with their API, but here goes.
I'm using the login button for my site. Upon click, the user will be presented with a pop up from FB telling them some basic info about my app (basic details, number of active users and permissions that it is requesting)
That's all fine and dandy. If the user accepts the app, the page will be reloaded and their info that is being requested from the app will be inserted into the DB and a session will be created.
session_start();
require_once("model/functions.php");
require_once("controller.php");
require_once("model/facebook_api/src/facebook.php");
$facebook = new Facebook(array(
'appId' => '123456789',
'secret' => '123456789',
'cookie' => true
));
$access_token = $facebook->getAccessToken();
$facebook->setAccessToken($access_token);
if($access_token != "")
{
$user = $facebook->getUser();
if($user != 0)
{
$user_profile = $facebook->api("/".$user);
$fb_id = $user;
$fb_first_name = $user_profile['first_name'];
$fb_last_name = $user_profile['last_name'];
$fb_email = $user_profile['email'];
// The FB user_id and all of their other info is correct. Seriously!!
echo $fb_id."<br />";
print_r($user_profile);
// Query the DB to see if this person's info from FB is in there
$query = "SELECT *
FROM users
WHERE fb_id = :fb_id";
$stmt = $db->prepare($query);
$stmt->execute(array(':fb_id' => $fb_id));
$count = $stmt->rowCount();
if($count == 1)
{
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$_SESSION['id'] = $row['user_id'];
$_SESSION['fb_id'] = $row['fb_id'];
$_SESSION['first'] = $row['first_name'];
$_SESSION['last'] = $row['last_name'];
$_SESSION['email'] = $row['email'];
$_SESSION['photo'] = $row['photo'];
$_SESSION['accuracy'] = $row['accuracy_rate'];
}
} else
{
$img_data = file_get_contents('https://graph.facebook.com/'.$fb_id.'/picture?type=large');
$save_path = 'img/profile_pics/large/';
file_put_contents($save_path.''.$fb_id.'.jpg', $img_data);
$insert = "INSERT INTO
users
(first_name,
last_name,
email,
photo,
fb_id,
accuracy_rate,
date_joined,
date_joined_int)
VALUES
(:first_name,
:last_name,
:email,
:photo,
:fb_id,
:points,
:date_joined,
:date_int)";
$params = array(':first_name' => $fb_first_name,
':last_name' => $fb_last_name,
':email' => $fb_email,
':photo' => $fb_id.'.jpg',
':fb_id' => $fb_id,
':points' => '100',
':date_joined' => date("M j, Y"),
':date_int' => idate('z'));
$stmt = $db->prepare($insert);
$stmt->execute($params)or die('error');
print_r($params);
// Query the DB to see if this person's info from FB is in there
$query = "SELECT *
FROM users
WHERE fb_id = :fb_id";
$stmt = $db->prepare($query);
$stmt->execute(array(':fb_id' => $fb_id));
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$_SESSION['id'] = $row['user_id'];
$_SESSION['fb_id'] = $row['fb_id'];
$_SESSION['first'] = $row['first_name'];
$_SESSION['last'] = $row['last_name'];
$_SESSION['email'] = $row['email'];
$_SESSION['photo'] = $row['photo'];
$_SESSION['accuracy'] = $row['accuracy_rate'];
}
}
} else
{
}
} else
{
}
A row is inserted into the DB each time the page is refreshed. No session is ever created. What's even stranger is that the facebook id that is inserted into the fb_id column in the DB belongs to an account that belongs to a test account that FB uses to test open graph actions that are submitted for approval. I know because after taking a deeper look at the DB, I saw a row in the DB that belonged to an FB open graph actions testers. The ID is "2147483647." That is clearly not the ID that is printed out when I printed out the $user_profile array. Furthermore, after the first time the page is reloaded, an insert query shouldn't even occur because the rowCount returned is set to 1. The insert query is only supposed to be executed if the user is a first time user. Sandbox mode isn't on. I thought might have had something to do with it. But, it didn't.
On an unrelated note, is there a bug with FB's api when it comes to doing
$facebook->api("/me");
That doesn't seem to work.
$facebook->api("/".$user);
seems to work just fine though.
Live example can be found here

Facebook user_id could go beyond the supported Integer length. Discovered this on iPhone SDK for a long ID eg. '10000328862128237'. I suspect that is your problem too as I got the exact same number '2147483647'.

Related

Multiple Database requests for login

I have three files that are relevant for this part of my login scenario:
/project/index.html
/project/api/user/login.php
/project/api/objects/user.php
The index.html has a simple login form in it, calling the ./api/user/login.php.
In this form I have a checkbox that is an option for the user in order to stay logged in or not.
If the user has selected this option, with every login, I would like to check if the credentials are correct (login function -> stmt1 in user.php) as well as to update the lastlogin (datetime), the identifier and securitytoken if the checkbox was set (login function -> stmt2 in user.php).
The user.php is included_once in the login.php that gets the values out of the index.html form and sends them to the login() function in the user.php.
Depending on the functions return value, the login.php decides if the login was successful or not.
The login itself (stmt1) works, but the update of lastlogin, identifier and securitytoken (stmt2) doesn't.
login.php
session_start();
// include database and object files
include_once '../config/database.php';
include_once '../objects/user.php';
// get database connection
$database = new Database();
$db = $database->getConnection();
// prepare user object
$user = new User($db);
// set ID property of user to be edited
$user->username = isset($_GET['username']) ? $_GET['username'] : die();
$user->password = base64_encode(isset($_GET['password']) ? $_GET['password'] : die());
$user->remember = isset($_GET['remember']) ? $_GET['remember'] : die();
$stmt1 = $user->login();
if($stmt1->rowCount() > 0){
// get retrieved row
$row1 = $stmt1->fetch(PDO::FETCH_ASSOC);
$_SESSION['userid'] = $row1['uid'];
// create array
$user_arr=array(
"status" => true,
"message" => "Login erfolgreich!",
"uid" => $row1['uid'],
"username" => $row1['username']
);
$stmt2 = $user->login();
$row2 = $stmt2->fetch(PDO::FETCH_ASSOC);
print_r($row2);
// create array
$user_arr=array(
"lastlogin" => $row2['lastlogin']
);
}
else{
$user_arr=array(
"status" => false,
"message" => "Benutzername und/oder Passwort nicht korrekt!",
);
}
// make it json format
print_r(json_encode($user_arr));
?>
user.php
function login(){
// select all query
$query1 = "SELECT
`uid`, `username`, `email`, `password`, `created`, `lastlogin`
FROM
" . $this->table_name . "
WHERE
username='".$this->username."' AND password='".$this->password."'";
// prepare query statement
$stmt1 = $this->conn->prepare($query1);
// execute query
$stmt1->execute();
return $stmt1;
// set up the remain logged in function
if(isset($this->remember)) {
$identifier = random_string();
$securitytoken = random_string();
$remember = ",identifier='".$identifier."',securitytoken='".$securitytoken."'";
setcookie("identifier",$identifier,time()+(3600*24*365)); //1 year valid
setcookie("securitytoken",$securitytoken,time()+(3600*24*365)); //1 year valid
} else {
$remember = "";
}
// update last login
$query2 = "UPDATE
" . $this->table_name . "
SET
`lastlogin` = '".date("Y-m-d H:i:s")."'
".$remember."
WHERE
username='".$this->username."' AND password='".$this->password."'";
// prepare query statement
$stmt2 = $this->conn->prepare($query2);
// execute query
$stmt2->execute();
return $stmt2;
}
function random_string(){
if(function_exists('random_bytes')) {
$bytes = random_bytes(16);
$str = bin2hex($bytes);
} else if(function_exists('openssl_random_pseudo_bytes')) {
$bytes = openssl_random_pseudo_bytes(16);
$str = bin2hex($bytes);
} else if(function_exists('mcrypt_create_iv')) {
$bytes = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
$str = bin2hex($bytes);
} else {
//secret key should have >12 random chars
$str = md5(uniqid('SECRET KEY', true));
}
return $str;
}
In the user.php after return $stmt1;
The code is returned and the cookies are not set
I would do this... Check login... If true, save cookies with id and token
And then periodically check if token and id correspond... If so... Just UPDATE the last login time.
Note: your prepared statement is vulnerable!! Dont append the parameters with '.' use placeholders instead, and dont encode the password, is better to hash it... Then compare hashes

JQuery Post to PHP Inserts data, but json response is null

I'm building a simple sign up form with AngularJS and sending the data to a PHP page using JQuery's $.post(). When I send the data, it correctly gets inserted into the database. However, the returned json that I am logging is showing my data fields as null.
Console:
{"status":"success","email":null,"id":null,"sessionId":null}
Javascript:
$.post("admin/addUser.php", {
email: form.email,
password: form.password
}).done(function(data){
console.log(data);
});
PHP:
$email = mysql_real_escape_string($_POST["email"]);
$password = md5(mysql_real_escape_string($_POST["password"]));
$sessionId = md5(uniqid(microtime()) . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']);
//Add this user to the database
$sql = mysql_query("INSERT INTO users (email, password, sessionId) VALUES ('".$email."', '".$password."', '".$sessionId."')");
if ($sql){
//Now find the user we just added
$getUser = mysql_query("SELECT * FROM users WHERE email = '".$email."' AND sessionId = '".$sessionId."'");
if ($getUser){
$row = mysql_fetch_array($getUser);
$user = array(
'status' => 'success',
'email' => $row['email'],
'id' => $row['id'],
'sessionId' => $row['sessionId']
);
echo json_encode($user);
}else{
$user = array(
'error' => mysql_error()
);
echo json_encode($user);
}
}else{
$user = array(
'error' => mysql_error()
);
echo json_encode($user);
}
Are you sure that you have only one record in here
$getUser = mysql_query("SELECT * FROM users WHERE email = '".$email."' AND sessionId = '".$sessionId."'");
Try to dump $row and see the response. BTW I would suggest you to add limit
$getUser = mysql_query("SELECT * FROM users WHERE email = '".$email."' AND sessionId = '".$sessionId."' LIMIT 1");
Ok, I dug around and found the answer to this. It was a mistake on my end. I was only storing the password and sessionId as varchar(30). When I was generating the sessionId and checking it against the DB, it was being cut off when it was stored, since I was only allowing 30 chars. I update to 255 and works as expected :-P.

Get data won't insert

I've been using $_GET data to send data across pages and it has been working fine.
What i have on one page is news. Each news article has its own specific ID (and this page works perfectly fine). I can click on an add me button next to each event to add myself as a volunteer for organising the BBQ for that event. However now i'm trying to click on an add button which can add other users to the BBQ.
I've checked to see if the $_GET data is returning anything on page load and it does, however the values are lost when i click submit. So, when i check to see if it returns anything inside the isset($_POST['userselect']), the values are lost:
Here is my code:
$rosterID = $_GET["rosterid"];
$eventID = $_GET["eventid"];
//if i check to see if they gets work here, they do.
if (hasRole2($connection, "Admin") || hasRole2($connection, "Moderator") || hasRole2($connection, "BBQ Moderator")){
$usernames[] = array();
if ($stmt = $connection->prepare("SELECT id, uid from people")){
$stmt->execute();
$stmt->bind_result($id, $username);
$stmt->store_result();
$form = new jqmForm();
$form->method('post');
$sel = $form->add(new jqmSelect('userselect','userselect','<p align="center">Select User:</p>'), true);
while ($stmt->fetch()){
$usernames[] = array('uid' => $username, 'id' => $id);
$optName = $username;
$optValue = $id;
$sel->add(new jqmOption($optName, $optValue, false));
$sel->attribute('data-native-menu', 'false');
}
$stmt->close();
$form->add(new jqmInput('submit', 'submit', 'submit', 'submit', '', 'b', true));
}
if (isset($_POST["userselect"])){
//if i check to see if the gets work here, they don't.
$personID = $_POST["userselect"];
if (rostered($connection, $personID, $rosterID, $eventID)){
$personID = $_POST["userselect"];
$p->addContent("<p align=center><font color = red>You have already rostered for this event</font></p>");
$login = $p->addContent("<font color=brown size=4><a href = news.php rel=external> Go back </a></font>");
$login->attribute('align', 'center');
}
else{
$search = "INSERT INTO RosterPeopleEvent (roster_id, person_id, news_id) VALUES (?, ?, ?)";
if (!$roster = $connection->prepare($search)){
$p->addContent("Inserting into RosterPeopleEvent Prepare failed: (" . $connection->errno . ") " . $connection->error);
}
else{
$roster->bind_param("iii", $_GET["rosterid"], $personID, $_GET["eventid"]);
$roster->execute();
}
}
}
}
Just added:
$form->action("url.php?rosterid=$rosterID&eventid=$eventID");
This worked.

How set a session after user has logged in with his Facebook account?

I'm working on a website and I quite new to php and programming in general. I managed to log in the user and I can access my user data from anywhere in my webpage with this:
if (logged_in() === true){
global $user_data;
$session_user_id = $_SESSION['user_id'];
$user_data = user_data($session_user_id,'username', 'id', 'password', 'first_name', 'last_name', 'email', 'imagename');
if (user_active($user_data['username']) === false) {
session_destroy();
header ('Location: logout.php' );
}
}
$errors = array();
?>
Hope it's clear so far. Now I also managed to register my user using his Facebook account.
fbfunctions.php:
require 'include.php';
function retrieve_fields($sf) {
return json_encode($sf);
}
function verify_fields($f,$sf) {
$fields = json_encode($sf);
return (strcmp($fields,$f) === 0);
}
function register_fbuser($resp) {
extract($resp["registration"],EXTR_PREFIX_ALL, "fb");
// prepare values
$fb_id = mysql_real_escape_string($resp["user_id"]);
$fb_birthday = date("Y-m-d" , strtotime($fb_birthday));
$fb_name = mysql_real_escape_string($fb_name);
$fb_first_name = mysql_real_escape_string($fb_first_name);
$fb_last_name = mysql_real_escape_string($fb_last_name);
$fb_username = mysql_real_escape_string($fb_username);
$fb_location = mysql_real_escape_string($fb_location["name"]);
$query_str = "INSERT INTO users(oauth_provider, oauth_uid, username, first_name, last_name, gender, birthday, location , email, imagename) VALUES ('facebook','$fb_id','$fb_name','$fb_first_name','$fb_last_name','$fb_gender', '$fb_birthday', '$fb_location','$fb_email','". $fb_id .".jpg')" or die(mysql_error());
mysql_query($query_str);
$imageData = file_get_contents("https://graph.facebook.com/" . $fb_id ."/picture");
file_put_contents("upload_img/" . $fb_id . ".jpg", $imageData);
}
function check_registration($fb, $fb_fields) {
if ($_REQUEST) {
$response = $fb->getSignedRequest();
if ($response && isset($response["registration_metadata"]["fields"])) {
$verified = verify_fields($response["registration_metadata"]["fields"], $fb_fields);
if (!$verified) { // fields don't match!
header("location: bad.php");
} else { // we verifieds the fields, insert the Data to the DB
$GLOBALS['congratulations'] = TRUE;
register_fbuser($response);
}
}
}
}
So now i have all my user data in the sql database and the user picture in a folder. I want to access the user data using for instance user_data['first_name'] instead of using Facebook graph api user_profile['first_name'] since I have already fetched all I need from Facebook.
Is there a way to verify if the user as logged in with Facebook and then set the session so I can simply use my functionlogged_in()?
I know that is a lot of code to go through and you may get lost in translation but I'm really confused.

Can somebody help me with posting a status on twitter?

I'm pretty much following this tutorial
http://net.tutsplus.com/tutorials/php/how-to-authenticate-users-with-twitter-oauth/
and i have everything working i can see the screen name when i call it as well as my status time line but for some reason i can not post a status. i have looked everywhere on the internet and everybody does it the same way but i cant get mine to work.
here is my twitter_oauth.php
<?php
require("twitteroauth.php");
session_start();
if(!empty($_GET['oauth_verifier']) && !empty($_SESSION['oauth_token']) && !empty($_SESSION['oauth_token_secret'])){
$twitteroauth = new TwitterOAuth('consumerkey', 'otherkey', $_SESSION['oauth_token'], $_SESSION['oauth_token_secret']);
//request the access token
$access_token = $twitteroauth->getAccessToken($_GET['oauth_verifier']);
$_SESSION['access_token'] = $access_token;
$user_info = $twitteroauth->get('account/verify_credentials');
//useful for seeing array key names
//print_r($user_info);
mysql_connect('localhost', 'usernamr', 'password');
mysql_select_db(' database_twitter');
if(isset($user_info->error)){
header('Location: twitter_login.php');
}else{
//find the user by its ID
$query = mysql_query("SELECT * FROM users WHERE oauth_provider = 'twitter' AND oauth_uid = ". $user_info->id);
$result = mysql_fetch_array($query);
//if it doesnt exist add
if(empty($result)){
$query = mysql_query("INSERT INTO users (oauth_provider, oauth_uid, username, oauth_token, oauth_secret) VALUES ('twitter', {$user_info->id}, '{$user_info->screen_name}', '{$access_token['oauth_token']}', '{$access_token['oauth_token_secret']}')");
$query = mysql_query("SELECT * FROM users WHERE id = " .mysql_insert_id());
$result = mysql_fetch_array($query);
}else{
// Update the tokens
$query = mysql_query("UPDATE users SET oauth_token = '{$access_token['oauth_token']}', oauth_secret = '{$access_token['oauth_token_secret']}' WHERE oauth_provider = 'twitter' AND oauth_uid = {$user_info->id}");
}
$_SESSION['id'] = $result['id'];
$_SESSION['username'] = $result['username'];
$_SESSION['oauth_uid'] = $result['oauth_uid'];
$_SESSION['oauth_provider'] = $result['oauth_provider'];
$_SESSION['oauth_token'] = $result['oauth_token'];
$_SESSION['oauth_secret'] = $result['oauth_secret'];
header('Location: twitter_update.php');
}
}else{
header('Location:twitter_login.php');
}
?>
and heres twitter_update.php
<?php
require("twitteroauth.php");
session_start();
?>
<h2>Hello <?php
if(!empty($_SESSION['username'])){
echo '#' .$_SESSION['username'];
}else{
echo 'Guest';
}
if(!empty($_SESSION['username'])){
$twitteroauth = new TwitterOAuth('key', 'key', $_SESSION['oauth_token'], $_SESSION['oauth_secret']);
$status_timeline = $twitteroauth->get('statuses/home_timeline', array('count' => 40));
$content = $twitteroauth->get('account/verify_credentials');
$twitteroauth->get('users/show', array('screen_name' => 'abraham'));
//$twitteroauth->post('statuses/update', array('status' => 'Testing out the twitter api with oauth'));
//print_r($status_timeline);
$twitteroauth->post('statuses/update', array('status' => "hello world"));
}
?>
</h2>
was trying to find out if it has been updated but couldn't find anything and i'm guessing it isn't
You are saving the access_token to $_SESSION['access_token'] in twitter_oauth.php but then in twitter_update.php you are using $_SESSION['oauth_token'].
twitter_oauth.php should also build a new TwitterOAuth object with the access_token before making requests to the API as the user.
You also have no error handling in the event that getting an access token fails.

Categories