I am able to login with user credentials with
try {
$user = ParseUser::logIn("myname", "mypass");
// Do stuff after successful login.
} catch (ParseException $error) {
// The login failed. Check error to see why.
}
but if I try to get the currentUser afterwards with
$currentUser = ParseUser::getCurrentUser();
if ($currentUser) {
// do stuff with the user
} else {
// show the signup or login page
}
$currentUser is not set.
I suspect this more to be a php "issue" that I don't know. I am greatful for any hint for keeping currentUser retained in my code as long I do not log out.
In order for the getCurrentUser() method to work, you must define the type of session storage to use. You can use the ParseSessionStorage class to achieve this:
use Parse\ParseClient;
use Parse\ParseUser;
use Parse\ParseSessionStorage;
session_start();
// Init parse: app_id, rest_key, master_key
ParseClient::initialize('xxx', 'yyy', 'zzz');
// set session storage
ParseClient::setStorage( new ParseSessionStorage() );
try {
$user = ParseUser::logIn("myname", "mypass");
// Do stuff after successful login.
} catch (ParseException $error) {
// The login failed. Check error to see why.
}
$currentUser = ParseUser::getCurrentUser();
print_r( $currentUser );
Related
I have the wamp server running on my laptop and I've got phpmyadmin working, and I'm trying to create a website that allows people to register to. But when I go to the register_new.php file, I get the following error:
Warning: mysqli::mysqli(): (HY000/1045): Access denied for user 'user'#'localhost' (using password: YES) in C:\wamp\www\db_fns.php on line 4
Call Stack
# Time Memory Function Location
1 0.0150 138784 {main}( ) ...\register_new.php:0
2 0.0191 172744 register( ) ...\register_new.php:40
3 0.0191 172760 db_connect( ) ...\user_auth_fns.php:10
4 0.0191 173720 mysqli ( ) ...\db_fns.php:4
Warning: mysqli_query(): Couldn't fetch mysqli in C:\wamp\www\user_auth_fns.php on line 13
Call Stack
# Time Memory Function Location
1 0.0150 138784 {main}( ) ...\register_new.php:0
2 0.0191 172744 register( ) ...\register_new.php:40
3 0.0860 173952 mysqli_query ( ) ...\user_auth_fns.php:13
And I get Could not execute query as a warning
And within my register_new.php file, I have:
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
// include function files for this application
require_once('require_fns.php');
//create short variable names
$email=$_POST['email'];
$username=$_POST['username'];
$passwd=$_POST['passwd'];
$passwd2=$_POST['passwd2'];
// start session which may be needed later
// start it now because it must go before headers
session_start();
try {
// check forms filled in
if (!filled_out($_POST)) {
throw new Exception('You have not filled the form out correctly. Please go back and try again.');
}
// email address not valid
if (!valid_email($email)) {
throw new Exception('That is not a valid email address. Please go back and try again.');
}
// passwords not the same
if ($passwd != $passwd2) {
throw new Exception('The passwords you entered do not match. Please go back and try again.');
}
// check password length is ok
// ok if username truncates, but passwords will get
// munged if they are too long.
if (!preg_match('/^(?=.*\d)(?=.*[A-Za-z])[0-9A-Za-z]{6,12}$/', $passwd)) {
throw new Exception('Your password must be between 6 and 12 characters inclusive. Please go back and try again.');
}
// attempt to register
// this function can also throw an exception
register($username, $email, $passwd);
// register session variable
$_SESSION['valid_user'] = $username;
// provide link to members page
do_html_header('Registration successful');
echo "Welcome " . $_POST["username"];
echo 'Your registration was successful.';
do_html_url('member.php', 'Go to members page');
// end page
do_html_footer();
}
catch (Exception $e) {
do_html_header('Warning:');
echo $e->getMessage();
do_html_footer();
exit;
}
?>
EDIT
The register function is as follows
function register($username, $email, $password) {
// register new person with db
// return true or error message
// connect to db
$conn = db_connect();
// check if username is unique
$result = mysqli_query($conn, "select * from user where username='".$username."'");
if (!$result) {
throw new Exception('Could not execute query');
}
if (mysqli_num_rows($result)>0) {
throw new Exception('That username is taken - go back and choose another one.');
}
// if ok, put in db
$result = mysqli_query($conn, "insert into user values
('".$username."', sha1('".$password."'), '".$email."')");
if (!$result) {
throw new Exception('Could not register you in database - please try again later.');
}
return true;
}
Also, the code I have to connect to the database is
<?php
function db_connect() {
$result = new mysqli('localhost','user','password');
if (!$result) {
throw new Exception('Could not connect to database server');
} else {
return $result;
}
}
?>
I have a schema called website and a database on that schema called user which has the following
create table user (
username varchar(16) primary key,
passwd char(40) not null,
email varchar(100) not null
);
EDIT2
It's still not working
The problem lies within your server login credentials. You're providing the wrong username and password and thus unable to connect to your database.
The default username and login is usually:
Username : 'root'
Password : '' // Empty string.
Change the login credentials in your db_connect() function.
<?php
function db_connect() {
$result = new mysqli('localhost','root','');
if (!$result) {
throw new Exception('Could not connect to database server');
} else {
return $result;
}
}
?>
I'm trying to make a website by using PHP and when I run it, it comes back The sharedweb.uniwebsite.ac.uk page isn't working sharedweb.uniwebsite.ac.uk is currently unable to handle this request. 500 And when I click on the Details tab, I get Press the reload button to resubmit the data needed to load the page. Which I have done. The previous pages do work and I'm trying to work on the login page and when I go Register button, that's when I get the error
EDIT
The code that's causing the error is
<?php
// include function files for this application
require_once('bookmark_fns.php');
//create short variable names
$email=$_POST['email'];
$username=$_POST['username'];
$passwd=$_POST['passwd'];
$passwd2=$_POST['passwd2'];
// start session which may be needed later
// start it now because it must go before headers
session_start();
try {
// check forms filled in
if (!filled_out($_POST)) {
throw new Exception('You have not filled the form out correctly. Please go back and try again.');
}
// email address not valid
if (!valid_email($email)) {
throw new Exception('That is not a valid email address. Please go back and try again.');
}
// passwords not the same
if ($passwd != $passwd2) {
throw new Exception('The passwords you entered do not match. Please go back and try again.');
}
// check password length is ok
// ok if username truncates, but passwords will get
// munged if they are too long.
if (!preg_match('/^(?=.*\d)(?=.*[A-Za-z])[0-9A-Za-z]{6,12}$/)', $passwd)) {
throw new Exception('Your password must be between 6 and 12 characters inclusive. Please go back and try again.');
}
// attempt to register
// this function can also throw an exception
register($username, $email, $passwd);
// register session variable
$_SESSION['valid_user'] = $username;
// provide link to members page
do_html_header('Registration successful');
echo "Welcome " $_POST["username"];
echo 'Your registration was successful. Go to the members page to start setting up your bookmarks!';
do_html_url('member.php', 'Go to members page');
// end page
do_html_footer();
}
catch (Exception $e) {
do_html_header('Warning:');
echo $e->getMessage();
do_html_footer();
exit;
}
?>
EDIT #2
It's still not working
There is an PHP error somewhere. To show the error add the following lines at the top of your script:
error_reporting(E_ALL);
ini_set("display_errors", 1);
(remove them after fixing the error, to not expose any secrets later)
Possibility 2 would be to check your error.log, which will tell you why its not working too.
I am attempting to implement the server side PHP facebook authentication code, to go with my front end Javascript Facebook authentication code.
For this, I am grabbing the current facebook session, storing it into the PGP $_SESSION array, and then using it to make a call to get the user's username.
On the 2nd time into the side, i check to see if we have the stored facebook session in the PHP $_SESSION array, and if so, I use that again to make the call to get the user name. This is where i recieve the "instance of __PHP_Incomplete_Class given" error message, when trying to use the stored session.
The reason i want to store the facebook session between page refreshes is that whenever i call $session = $helper->getSession(); a second time after the user logs in, i receive a message "this authorization code has already been used". I read somewhere that you need to store the facebook session, instead of calling for a new one each refresh, as the facebook token was already consumed in getting you the first session object.
Can anyone help me figure out how to store the facebook session in the PHP $_SESSION array correctly, and be able to pull it back out, and use it to make calls to facebook?
I am using the latest facebook JS sdk and the latest facebook PHP sdk.
CODE:
<?php
session_start();
require_once ('facebookphpsdkv4/src/Facebook/GraphObject.php');
require_once ('facebookphpsdkv4/src/Facebook/GraphUser.php');
require_once ('facebookphpsdkv4/src/Facebook/GraphSessionInfo.php');
require_once ('facebookphpsdkv4/src/Facebook/Entities/AccessToken.php');
require_once ('facebookphpsdkv4/src/Facebook/FacebookSession.php');
require_once ('facebookphpsdkv4/src/Facebook/Entities/SignedRequest.php');
require_once ('facebookphpsdkv4/src/Facebook/FacebookSignedRequestFromInputHelper.php');
require_once ('facebookphpsdkv4/src/Facebook/FacebookJavaScriptLoginHelper.php');
require_once ('facebookphpsdkv4/src/Facebook/HttpClients/FacebookHttpable.php');
require_once ('facebookphpsdkv4/src/Facebook/HttpClients/FacebookCurl.php');
require_once ('facebookphpsdkv4/src/Facebook/HttpClients/FacebookCurlHttpClient.php');
require_once ('facebookphpsdkv4/src/Facebook/FacebookResponse.php');
require_once ('facebookphpsdkv4/src/Facebook/FacebookRequest.php');
require_once ('facebookphpsdkv4/src/Facebook/FacebookSDKException.php');
require_once ('facebookphpsdkv4/src/Facebook/FacebookRequestException.php');
require_once ('facebookphpsdkv4/src/Facebook/FacebookAuthorizationException.php');
useFacebookGraphObject;
useFacebookGraphUser;
useFacebookGraphSessionInfo;
useFacebookEntitiesAccessToken;
useFacebookFacebookSession;
useFacebookEntitiesSignedRequest;
useFacebookFacebookSignedRequestFromInputHelper;
useFacebookFacebookJavaScriptLoginHelper;
useFacebookHttpClientsFacebookHttpable;
useFacebookHttpClientsFacebookCurl;
useFacebookHttpClientsFacebookCurlHttpClient;
useFacebookFacebookResponse;
useFacebookFacebookRequest;
useFacebookFacebookSDKException;
useFacebookFacebookRequestException;
useFacebookFacebookAuthorizationException;
FacebookSession::setDefaultApplication('AppID', 'AppSecret');
if (isset($_SESSION['session']))
{
echo 'session set';
$session = $_SESSION['session'];
}
else
{
$helper = new FacebookJavaScriptLoginHelper();
try
{
$session = $helper->getSession();
$_SESSION['session'] = $session;
}
catch(FacebookRequestException $e)
{
echo "Exception occured, code: " . $e->getCode();
echo " with message: " . $e->getMessage();
}
catch(Exception $e)
{
echo "Exception occured, code: " . $e->getCode();
echo " with message: " . $e->getMessage();
}
}
if ($session)
{
try
{
$user_profile = (new FacebookRequest($session, 'GET', '/me'))->execute()->getGraphObject(GraphUser::className());
echo "Name: " . $user_profile->getName();
}
catch(FacebookRequestException $e)
{
echo "Exception occured, code: " . $e->getCode();
echo " with message: " . $e->getMessage();
}
}
?>
You have an __PHP_Incomplete_Class error because you get your sessions (with session_start() call) before including you class files.
There are objects of a type unknown by PHP (as your requires are after your session_start()) in your session variables, so PHP don't know how to "rebuild" theses objects.
The situation: I have a finished Facebook canvas app (PHP/CodeIgniter), I just need to add the Facebook-related options such as sharing and inviting friends.
Current task: getting the list of invitable friends from the PHP SDK.
Relevant documentation: https://developers.facebook.com/docs/games/invitable-friends/v2.0
The code: in my Facebook library, I have created the following function.
/**
* Returns the current user's invitable friends
*/
public function get_invitable_friends() {
if ( $this->session ) {
$request = ( new FacebookRequest( $this->session, 'GET', '/me/invitable_friends' ) )->execute();
$graphObject = $request->getGraphObject();
return $graphObject;
}
return false;
}
The condition if($this->session) is because it doesn't make sense to try anything if there's no Facebook session in the first place. This will come into play later.
I've tried calling this function in two ways. The first way works and the second doesn't. I'm gonna present both, and then somebody will hopefully explain to me why the second way doesn't work and how to fix it, as I'd much prefer to use that.
First (working) way:
Call the function from the main controller's index() method, as the page loads. The function correctly returns a list of my friends.
Second (non-working) way:
Create this function in the controller:
//load list of friends we can invite to play the game
public function load_invitable_friends()
{
$this->load->library('facebook');
$list = $this->facebook->get_invitable_friends();
var_dump($list);
}
Then call it through AJAX, like:
function loadInvites(){
$.post(base+"main/load_invitable_friends/",function(resp){
$('#slide_6_inner').html(resp);
});
}
After this call, the content of the slide_6_inner div should contain the list of friends, as dumped by var_dump. However, the content is bool(false), indicating that the Facebook session is no longer present.
If I remove the condition if( $this->session ) from the get_invitable_friends() method, then this error happens:
A PHP Error was encountered
Severity: 4096
Message: Argument 1 passed to Facebook\FacebookRequest::__construct() must be an instance of Facebook\FacebookSession, null given, called in /home/lights/public_html/appname/application/libraries/facebook/Facebook.php on line 125 and defined
Filename: Facebook/FacebookRequest.php
Line Number: 182
The session in Facebook.php is initially created with the following code.
$this->ci =& get_instance();
// Initialize the SDK
FacebookSession::setDefaultApplication( $api_id, $api_secret) );
$this->helper = new FacebookCanvasLoginHelper();
$this->session = $this->helper->getSession();
To sum up - why is this problem occurring and how do I fix it?
In order to retrieve the session from the server side, you will need to first create a session using the FacebookCanvasLoginHelper. This class takes a signed request from Facebook supplied in a POST request, and exchanges it for a FacebookSession object. This should only really be done one when a user logs into your application:
$helper = new FacebookCanvasLoginHelper();
try {
$session = $helper->getSession();
} catch (FacebookRequestException $ex) {
// When Facebook returns an error
} catch (\Exception $ex) {
// When validation fails or other local issues
}
if ($session) {
// Store this in your PHP session somewhere:
$token = $session->getToken();
}
Thereafter, you should use the token to initialize the session:
$token = //GET THIS FROM SESSION
use Facebook\FacebookSession;
FacebookSession::setDefaultApplication('app-id', 'app-secret');
// If you already have a valid access token:
$session = new FacebookSession($token);
// To validate the session:
try {
$session->validate();
} catch (FacebookRequestException $ex) {
// Session not valid, Graph API returned an exception with the reason.
echo $ex->getMessage();
} catch (\Exception $ex) {
// Graph API returned info, but it may mismatch the current app or have expired.
echo $ex->getMessage();
}
Well, it seems you are not doing anything if session does not exists, just returning false. The problem is occuring because the session is expired/or does not exists, so you have to validate the fbToken and set the session again or create a new one.
You can create a function that checks if user is logged in, like:
function CheckFbUser() {
// Check if existing session exists
if (isset($_SESSION) && isset($_SESSION['fb_token'])) {
// Create new session from saved access_token
$session = new FacebookSession($_SESSION['fb_token']);
// Validate token
try {
if (!$session->validate()) {
$session = null;
}
} catch (Exception $e) {
// Catch any exceptions
$session = null;
}
} else {
// No session
try {
$session = $helper->getSessionFromRedirect();
} catch(FacebookRequestException $e) {
// handle it for facebook exceptions
} catch(Exception $e) {
// handle your php exceptions
}
}
// Check if a session exists
if ( isset( $session ) ) {
// Save the session
$_SESSION['fb_token'] = $session->getToken();
// Create session using saved token or the new one we generated at login
$session = new FacebookSession( $session->getToken() );
// USUALLY, here, people show the Logout Button, or anything alike, but you could it
// to return true, and then continue to run your code.
} else {
// No session
// USUALLY, here, people show the Login Button, or anything alike, you could
// use it to return false, or redirect user to login first.
$helper->getLoginUrl();
}
}
That is just an simple code, to check if user is logged in or not before you run the requests.
So the problem is, when /MVCTest/manage/dashboard is called, the authenticator is failing because authenticate (a method in the authenticator class) is not finding $_SESSION['user_id'], so it kicks the user back to the login page.
However, if I change the action below to:
action="/MVCTest/manage/login?target=MVCTest/manage/dashboard"
and add the same login function form the index controller to the manageController, everything works fine, but this means I would have to have a login function in every controller that has a page I want to login from (which is every page since I want a user dashboard).
So how do I get the $_SESSION to presist between controllers so I can have a single controller responsible for logging a user in/out?
First, some code...
action="/MVCTest/index/login?target=MVCTest/manage/dashboard" calls the login action of the indexController.
<?php
Class indexController Extends Core_Controller {
public function login(){
$this->registry->authenticator->login($_POST);
}
}
?>
The authenticator object was created in the bootstrap and assigned to the registry. Now for the authenticator object.
<?php
Class Authenticator Extends Base_Model {
public function login($credentials){
//Select user from the database based on email/username
try{
$STH = $this->db->prepare("SELECT * FROM user_account WHERE email = ? OR username = ?");
$STH->bindParam(1, $credentials['login']);
$STH->bindParam(2, $credentials['login']);
$STH->execute();
while($user = $STH->fetch(PDO::FETCH_OBJ)){
$password = $user->user_salt.$credentials['password'];
$password = $this->hashData($password);
try{
if($password === $user->password){
//Active and Verified user exists, set sessions
$random = $this->generateRandomString();
//Build the token
$token = $_SERVER["HTTP_USER_AGENT"] . $random;
$token = $this->hashData($token);
//Setup session variables
session_start();
$_SESSION["token"] = $token;
$_SESSION["user_id"] = $user->id;
//Delete old session records for the user
$STH = $this->db->prepare("DELETE FROM user_session WHERE user_account_id = ?");
$STH->bindParam(1, $user->id);
$STH->execute();
//Insert new session records for the user
try{
$STH = $this->db->prepare("INSERT INTO user_session (user_account_id, session_id, token)
VALUES (?,'".session_id()."', ?);");
$STH->bindParam(1, $user->id);
$STH->bindParam(2, $token);
$STH->execute();
header("Location: /{$_GET['target']}");
exit;
} catch (PDOException $e){
file_put_contents(__SITE_PATH."/logs/errors/MySQLErrors", $e->getMessage()."\n", FILE_APPEND);
die($e->getMessage());
}
} else {
throw new Exception("Password is incorrect!");
}
} catch (Exception $e){
file_put_contents(__SITE_PATH."/logs/errors/LoginErrors", $e->getMessage()."\n", FILE_APPEND);
die($e->getMessage());
}
}
//Email/Username not found
throw new Exception("Email/Username not found!");
} catch (Exception $e) {
file_put_contents(__SITE_PATH."/logs/errors/LoginErrors", $e->getMessage()."\n", FILE_APPEND);
die($e->getMessage());
} catch (PDOException $e){
file_put_contents(__SITE_PATH."/logs/errors/MySQLErrors", $e->getMessage()."\n", FILE_APPEND);
die($e->getMessage());
}
}
}
?>
And finally, my manageController
<?php
session_name();
session_set_cookie_params(3600, "/MVCTest/manage/");
session_start();
Class manageController Extends Core_Controller {
public function index() {
if(isset($_SESSION['user_id'])){
header("Location: /MVCTest/manage/dashboard");
exit;
}
$this->registry->template->show('manage/index');
}
public function dashboard(){
$this->registry->authenticator->authenticate("/MVCTest/manage/");
$this->registry->template->show('manage/dashboard');
}
}
?>
I found the answer. Leave session_name();
session_set_cookie_params(3600, __SITE_PATH.'/MVCTest/manage/'); in the manageController while moving session_start(); to the beginning of the extended Core_Controller while adding a public login function.
The result is that every page can log somebody in; however, I feel like this is bad practice. The problem I see is that every single page call will start a session regardless of if the user is logged in or not. I get the feeling that this is bad, any suggestions?
Look at this code:
//Setup session variables
session_start();
$_SESSION["token"] = $token;
$_SESSION["user_id"] = $user->id;
You must use
session_start();
At the beginning of the file.
Read more about session_start