how can i create user profile links? - php

I have a profile.php wich echo the user info i want. After searching alittle on google and watching a few tutorials, im stuck. I want every user registered to my website to get a profile (unique), that is access able for everyone. The link i plan on using is example.com/user/id where "id" is replaced with the id of the users profile you want to view.
Register.php
// This if statement checks to determine whether the registration form has been submitted
// If it has, then the registration code is run, otherwise the form is displayed
if(!empty($_POST))
{
// Ensure that the user has entered a non-empty username
if(empty($_POST['username']))
{
// Note that die() is generally a terrible way of handling user errors
// like this. It is much better to display the error with the form
// and allow the user to correct their mistake. However, that is an
// exercise for you to implement yourself.
die("<div class='red'>Please enter a username.</div>");
}
// Ensure that the user has entered a non-empty password
if(empty($_POST['password']))
{
die("<div class='red'>Please enter a password.</div>");
}
// Make sure the user entered a valid E-Mail address
// filter_var is a useful PHP function for validating form input, see:
// http://us.php.net/manual/en/function.filter-var.php
// http://us.php.net/manual/en/filter.filters.php
if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
{
die("<div class='red'>Invalid E-Mail Address</div>");
}
// We will use this SQL query to see whether the username entered by the
// user is already in use. A SELECT query is used to retrieve data from the database.
// :username is a special token, we will substitute a real value in its place when
// we execute the query.
$query = "
SELECT
1
FROM users
WHERE
username = :username
";
// This contains the definitions for any special tokens that we place in
// our SQL query. In this case, we are defining a value for the token
// :username. It is possible to insert $_POST['username'] directly into
// your $query string; however doing so is very insecure and opens your
// code up to SQL injection exploits. Using tokens prevents this.
// For more information on SQL injections, see Wikipedia:
// http://en.wikipedia.org/wiki/SQL_Injection
$query_params = array(
':username' => $_POST['username']
);
try
{
// These two statements run the query against your database table.
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("<div class='red'>Failed to run query: </div>" . $ex->getMessage());
}
// The fetch() method returns an array representing the "next" row from
// the selected results, or false if there are no more rows to fetch.
$row = $stmt->fetch();
// If a row was returned, then we know a matching username was found in
// the database already and we should not allow the user to continue.
if($row)
{
die("<div class='red'>This username is already in use</div>");
}
// Now we perform the same type of check for the email address, in order
// to ensure that it is unique.
$query = "
SELECT
1
FROM users
WHERE
email = :email
";
$query_params = array(
':email' => $_POST['email']
);
try
{
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
die("<div class='red'>Failed to run query: </div>" . $ex->getMessage());
}
$row = $stmt->fetch();
if($row)
{
die("<div class='red'>This email address is already registered</div>");
}
// An INSERT query is used to add new rows to a database table.
// Again, we are using special tokens (technically called parameters) to
// protect against SQL injection attacks.
$query = "
INSERT INTO users (
username,
password,
salt,
email
) VALUES (
:username,
:password,
:salt,
:email
)
";
// A salt is randomly generated here to protect again brute force attacks
// and rainbow table attacks. The following statement generates a hex
// representation of an 8 byte salt. Representing this in hex provides
// no additional security, but makes it easier for humans to read.
// For more information:
// http://en.wikipedia.org/wiki/Salt_%28cryptography%29
// http://en.wikipedia.org/wiki/Brute-force_attack
// http://en.wikipedia.org/wiki/Rainbow_table
$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
// This hashes the password with the salt so that it can be stored securely
// in your database. The output of this next statement is a 64 byte hex
// string representing the 32 byte sha256 hash of the password. The original
// password cannot be recovered from the hash. For more information:
// http://en.wikipedia.org/wiki/Cryptographic_hash_function
$password = hash('sha256', $_POST['password'] . $salt);
// Next we hash the hash value 65536 more times. The purpose of this is to
// protect against brute force attacks. Now an attacker must compute the hash 65537
// times for each guess they make against a password, whereas if the password
// were hashed only once the attacker would have been able to make 65537 different
// guesses in the same amount of time instead of only one.
for($round = 0; $round < 65536; $round++)
{
$password = hash('sha256', $password . $salt);
}
// Here we prepare our tokens for insertion into the SQL query. We do not
// store the original password; only the hashed version of it. We do store
// the salt (in its plaintext form; this is not a security risk).
$query_params = array(
':username' => $_POST['username'],
':password' => $password,
':salt' => $salt,
':email' => $_POST['email']
);
try
{
// Execute the query to create the user
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("<div class='red'>Failed to run query:</div> " . $ex->getMessage());
}
// This redirects the user back to the login page after they register
header("Location: /login");
// Calling die or exit after performing a redirect using the header function
// is critical. The rest of your PHP script will continue to execute and
// will be sent to the user if you do not die or exit.
die("Redirecting to /login");
}
?>
Login.php
<?php
// This variable will be used to re-display the user's username to them in the
// login form if they fail to enter the correct password. It is initialized here
// to an empty value, which will be shown if the user has not submitted the form.
$submitted_username = '';
// This if statement checks to determine whether the login form has been submitted
// If it has, then the login code is run, otherwise the form is displayed
if(!empty($_POST))
{
// This query retreives the user's information from the database using
// their username.
$query = "
SELECT
id,
username,
password,
salt,
email,
bio,
warnings,
clan,
timestamp,
title,
FROM users
WHERE
username = :username
";
// The parameter values
$query_params = array(
':username' => $_POST['username']
);
try
{
// Execute the query against the database
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("<div class='red'>Failed to run query: </div>" . $ex->getMessage());
}
// This variable tells us whether the user has successfully logged in or not.
// We initialize it to false, assuming they have not.
// If we determine that they have entered the right details, then we switch it to true.
$login_ok = false;
// Retrieve the user data from the database. If $row is false, then the username
// they entered is not registered.
$row = $stmt->fetch();
if($row)
{
// Using the password submitted by the user and the salt stored in the database,
// we now check to see whether the passwords match by hashing the submitted password
// and comparing it to the hashed version already stored in the database.
$check_password = hash('sha256', $_POST['password'] . $row['salt']);
for($round = 0; $round < 65536; $round++)
{
$check_password = hash('sha256', $check_password . $row['salt']);
}
if($check_password === $row['password'])
{
// If they do, then we flip this to true
$login_ok = true;
}
}
// If the user logged in successfully, then we send them to the private members-only page
// Otherwise, we display a login failed message and show the login form again
if($login_ok)
{
// Here I am preparing to store the $row array into the $_SESSION by
// removing the salt and password values from it. Although $_SESSION is
// stored on the server-side, there is no reason to store sensitive values
// in it unless you have to. Thus, it is best practice to remove these
// sensitive values first.
unset($row['salt']);
unset($row['password']);
// This stores the user's data into the session at the index 'user'.
// We will check this index on the private members-only page to determine whether
// or not the user is logged in. We can also use it to retrieve
// the user's details.
$_SESSION['user'] = $row;
// Redirect the user to the private members-only page.
header("Location: /");
die("Redirecting to: /");
}
else
{
// Tell the user they failed
print("<div class='red'>Login Failed.</div>");
// Show them their username again so all they have to do is enter a new
// password. The use of htmlentities prevents XSS attacks. You should
// always use htmlentities on user submitted values before displaying them
// to any users (including the user that submitted them). For more information:
// http://en.wikipedia.org/wiki/XSS_attack
$submitted_username = htmlentities($_POST['username'], ENT_QUOTES, 'UTF-8');
}
}
?>
Profile.php
<!DOCTYPE html>
<html>
<head>
<!--START HEAD-->
<?php include 'head.php'; ?>
<link rel='stylesheet' type='text/css' href="/profile.css"/>
<title><?php print htmlentities($_SESSION['user']['username'], ENT_QUOTES, 'UTF-8'); ?>'s profile</title>
<!--END HEAD-->
</head>
<body>
<!--START BODY-->
<?php
// At the top of the page we check to see whether the user is logged in or not
if(empty($_SESSION['user']))
{
include'navigationbar.php';
} else {
include'navigationbar2.php';
}
?>
<!--MAIN CONTENT-->
<div class="movedown"></div>
<div class="content">
<!--MAIN PROFILE-->
<div class="username">
<?php if(empty($_SESSION['user']['clan'])){
print "";
}else{
print "[".htmlentities($_SESSION['user']['clan'], ENT_QUOTES, 'UTF-8')."]";} ?>
<?php print htmlentities($_SESSION['user']['username'], ENT_QUOTES, 'UTF-8'); ?>
<div class="fr">ID: <?php print htmlentities($_SESSION['user']['id'], ENT_QUOTES, 'UTF-8'); ?></div></div>
<div class="spacing"></div>
<div class="fl">
<!--AVATAR-->
<div class="avatarback">
<div class="avatar"><img src="/profile/avatar/default.jpg" width="180px"/></div>
</div>
<!--TITLES / SIGNS-->
<div class="signs"><br/>
<div class="title"><div class="fl">Title: </div>
<div class="fr"><?php print htmlentities($_SESSION['user']['title'], ENT_QUOTES, 'UTF-8'); ?> </div></div><!--TITLE-->
<div class="spacing"></div>
<div class="warnings"><div class="fl">Warnings: </div>
<div class="fr"><?php print htmlentities($_SESSION['user']['warnings'], ENT_QUOTES, 'UTF-8'); ?> </div></div><!--WARNINGS-->
<div class="spacing"></div>
<div class="joined"><div class="fl">Joined: </div>
<div class="fr"><?php print htmlentities($_SESSION['user']['timestamp'], ENT_QUOTES, 'UTF-8'); ?> </div></div><!--JOINED-->
</div>
</div>
<div class="padding"></div>
<!--BIO-->
<div class="bioback">
<?php if(empty($_SESSION['user']['bio'])){
print "This user has not set any bio yet...";
}else{
print htmlentities($_SESSION['user']['bio'], ENT_QUOTES, 'UTF-8');} ?>
</div>
<!--SETTINGS TAB-->
<div class="etc-back">
<div>Message</div>
<div class="spacing2"></div>
<div>Settings</div>
<div class="spacing2"></div>
<div>AdminPanel</div>
</div>
<br/>
<br/>
<div class="padding"></div>
<div class="email">
<div class="fl">E-mail:</div><div class="fr"><?php print htmlentities($_SESSION['user']['email'], ENT_QUOTES, 'UTF-8'); ?></div>
</div>
<div class="spacing"></div>
<div class="padding"></div>
<div class="email">
<div class="fl">Website:</div><div class="fr"><?php print "<a href='". htmlentities($_SESSION['user']['website'], ENT_QUOTES, 'UTF-8')."'>".htmlentities($_SESSION['user']['website'], ENT_QUOTES, 'UTF-8')."</a>"; ?></div>
</div>
<div class="spacing"></div>
<div class="padding"></div>
<div class="email">
<div class="fl">Clan Page:</div><div class="fr"><?php if(empty($_SESSION['user']['clanpage'])){
print "No Clan Page Found!";
}else{
print htmlentities($_SESSION['user']['clanpage'], ENT_QUOTES, 'UTF-8');} ?></div>
</div>
</div>
</body>
</html>

Related

nr. bound variables, missmatch number tokens

Hi I have been scanning the answers on this subject but they seem to be individual at most, so here goes. My code is from a free repository and it works when I remove the addition I have maid.
I added "uname" because I wanted the users to be greeted by their name and not their username. It may be stupied but I like it this way. But I am missing something. My code is here:
<?php
// First we execute our common code to connection to the database and start the session
require("common.php");
// At the top of the page we check to see whether the user is logged in or not
if(empty($_SESSION['username']))
{
// If they are not, we redirect them to the login page.
header("Location: login.php");
// Remember that this die statement is absolutely critical. Without it,
// people can view your members-only content without logging in.
die("Redirecting to login.php");
}
// This if statement checks to determine whether the edit form has been submitted
// If it has, then the account updating code is run, otherwise the form is displayed
if(!empty($_POST))
{
// Make sure the user entered a valid E-Mail address
if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
{
die("Invalid E-Mail Address");
}
// If the user is changing their E-Mail address, we need to make sure that
// the new value does not conflict with a value that is already in the system.
// If the user is not changing their E-Mail address this check is not needed.
if($_POST['email'] != $_SESSION['username']['email'])
{
// Define our SQL query
$query = "
SELECT
*
FROM admin_users
WHERE
email = :email
";
// Define our query parameter values
$query_params = array(
':email' => $_POST['email'],
':uname' => $_POST['uname']
);
try
{
// Execute the query
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// Retrieve results (if any)
$row = $stmt->fetch();
if($row)
{
die("This E-Mail address is already in use");
}
}
// If the user entered a new password, we need to hash it and generate a fresh salt
// for good measure.
if(!empty($_POST['password']))
{
$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
$password = hash('sha256', $_POST['password'] . $salt);
for($round = 0; $round < 65536; $round++)
{
$password = hash('sha256', $password . $salt);
}
}
else
{
// If the user did not enter a new password we will not update their old one.
$password = null;
$salt = null;
}
// Initial query parameter values
$query_params = array(
':email' => $_POST['email'],
':uname' => $_POST['uname'],
':user_id' => $_SESSION['username']['id'],
);
// If the user is changing their password, then we need parameter values
// for the new password hash and salt too.
if($password !== null)
{
$query_params[':password'] = $password;
$query_params[':salt'] = $salt;
}
// Note how this is only first half of the necessary update query. We will dynamically
// construct the rest of it depending on whether or not the user is changing
// their password.
$query = "
UPDATE admin_users
SET
uname = :uname
email = :email
username = :username
";
// If the user is changing their password, then we extend the SQL query
// to include the password and salt columns and parameter tokens too.
if($password !== null)
{
$query .= "
, password = :password
, salt = :salt
";
}
// Finally we finish the update query by specifying that we only wish
// to update the one record with for the current user.
$query .= "
WHERE
id = :user_id
";
try
{
// Execute the query
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// Now that the user's E-Mail address has changed, the data stored in the $_SESSION
// array is stale; we need to update it so that it is accurate.
$_SESSION['username']['email'] = $_POST['email'];
// This redirects the user back to the members-only page after they register
header("Location: private.php");
// Calling die or exit after performing a redirect using the header function
// is critical. The rest of your PHP script will continue to execute and
// will be sent to the user if you do not die or exit.
die("Redirecting to private.php");
}
?>
<?php include("header.php"); ?>
<?php include("menu.php"); ?>
<div id="header_wrapper">
<h1>Edit Account</h1>
<form action="edit_account.php" method="post">
Username:<br />
<b><?php echo htmlentities($_SESSION['username']['username'], ENT_QUOTES, 'UTF-8'); ?></b>
<br /><br />
Navn:<br />
<input type="text" name="uname" value="<?php echo htmlentities($_SESSION['username']['uname'], ENT_QUOTES, 'UTF-8'); ?>" />
<br /><br />
Brugernavn:<br />
<input type="text" name="username" value="<?php echo htmlentities($_SESSION['username']['username'], ENT_QUOTES, 'UTF-8'); ?>" />
<br /><br />
E-Mail Address:<br />
<input type="text" name="email" value="<?php echo htmlentities($_SESSION['username']['email'], ENT_QUOTES, 'UTF-8'); ?>" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" /><br />
<i>(leave blank if you do not want to change your password)</i>
<br /><br />
<input type="submit" value="Update Account" />
</form>
</div>
<?php include("footer.php"); ?>
The error
Error: "Failed to run query: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens"

PHP/MySQL Login System not checking password

I'm trying to follow along with a tutorial for creating a login system for a website but some of the code isn't running. Signing up works fine and I can see the entries in my database, but logging in fails even if I have the correct details. Here is my login.php code:
<?php
// First we execute our common code to connection to the database and start the session
require("common.php");
// This variable will be used to re-display the user's username to them in the
// login form if they fail to enter the correct password. It is initialized here
// to an empty value, which will be shown if the user has not submitted the form.
$submitted_username = '';
// This if statement checks to determine whether the login form has been submitted
// If it has, then the login code is run, otherwise the form is displayed
if(!empty($_POST))
{
// This query retrieves the user's information from the database using
// their username.
$query = "SELECT id, username, password, salt, email FROM users WHERE username = :username";
// The parameter values
$query_params = array(
':username' => $_POST['username']
);
try
{
// Execute the query against the database
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// This variable tells us whether the user has successfully logged in or not.
// We initialize it to false, assuming they have not.
// If we determine that they have entered the right details, then we switch it to true.
$login_ok = false;
// Retrieve the user data from the database. If $row is false, then the username
// they entered is not registered.
$row = $stmt->fetch();
if($row)
{
// Using the password submitted by the user and the salt stored in the database,
// we now check to see whether the passwords match by hashing the submitted password
// and comparing it to the hashed version already stored in the database.
$check_password = hash('sha256', $_POST['password'] . $row['salt']);
for($round = 0; $round < 65536; $round++)
{
print("Checking password");
$check_password = hash('sha256', $check_password . $row['salt']);
}
if($check_password === $row['password'])
{
// If they do, then we flip this to true
$login_ok = true;
}
}
// If the user logged in successfully, then we send them to the private members-only page
// Otherwise, we display a login failed message and show the login form again
if($login_ok)
{
// Here I am preparing to store the $row array into the $_SESSION by
// removing the salt and password values from it. Although $_SESSION is
// stored on the server-side, there is no reason to store sensitive values
// in it unless you have to. Thus, it is best practice to remove these
// sensitive values first.
unset($row['salt']);
unset($row['password']);
// This stores the user's data into the session at the index 'user'.
// We will check this index on the private members-only page to determine whether
// or not the user is logged in. We can also use it to retrieve
// the user's details.
$_SESSION['user'] = $row;
// Redirect the user to the private members-only page.
header("Location: secret.html");
die("Redirecting to: secret.html");
}
else
{
// Tell the user they failed
//print("Login Failed.");
// Show them their username again so all they have to do is enter a new
// password. The use of htmlentities prevents XSS attacks. You should
// always use htmlentities on user submitted values before displaying them
// to any users (including the user that submitted them). For more information:
// http://en.wikipedia.org/wiki/XSS_attack
$submitted_username = htmlentities($_POST['username'], ENT_QUOTES, 'UTF-8');
}
}
?>
<h1>Login</h1>
<form action="login.php" method="post">
Username:<br />
<input type="text" name="username" value="<?php echo $submitted_username; ?>" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" />
<br /><br />
<input type="submit" value="Login" />
</form>
Register
Here is my register.php code:
<?php
// First we execute our common code to connection to the database and start the session
require("common.php");
// This if statement checks to determine whether the registration form has been submitted
// If it has, then the registration code is run, otherwise the form is displayed
if(!empty($_POST))
{
// Ensure that the user has entered a non-empty username
if(empty($_POST['username']))
{
// Note that die() is generally a terrible way of handling user errors
// like this. It is much better to display the error with the form
// and allow the user to correct their mistake. However, that is an
// exercise for you to implement yourself.
die("Please enter a username.");
}
// Ensure that the user has entered a non-empty password
if(empty($_POST['password']))
{
die("Please enter a password.");
}
// Make sure the user entered a valid E-Mail address
// filter_var is a useful PHP function for validating form input, see:
// http://us.php.net/manual/en/function.filter-var.php
// http://us.php.net/manual/en/filter.filters.php
if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
{
die("Invalid E-Mail Address");
}
// We will use this SQL query to see whether the username entered by the
// user is already in use. A SELECT query is used to retrieve data from the database.
// :username is a special token, we will substitute a real value in its place when
// we execute the query.
$query = "
SELECT
1
FROM users
WHERE
username = :username
";
// This contains the definitions for any special tokens that we place in
// our SQL query. In this case, we are defining a value for the token
// :username. It is possible to insert $_POST['username'] directly into
// your $query string; however doing so is very insecure and opens your
// code up to SQL injection exploits. Using tokens prevents this.
// For more information on SQL injections, see Wikipedia:
// http://en.wikipedia.org/wiki/SQL_Injection
$query_params = array(
':username' => $_POST['username']
);
try
{
// These two statements run the query against your database table.
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// The fetch() method returns an array representing the "next" row from
// the selected results, or false if there are no more rows to fetch.
$row = $stmt->fetch();
// If a row was returned, then we know a matching username was found in
// the database already and we should not allow the user to continue.
if($row)
{
die("This username is already in use");
}
// Now we perform the same type of check for the email address, in order
// to ensure that it is unique.
$query = "
SELECT
1
FROM users
WHERE
email = :email
";
$query_params = array(
':email' => $_POST['email']
);
try
{
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
$row = $stmt->fetch();
if($row)
{
die("This email address is already registered");
}
// An INSERT query is used to add new rows to a database table.
// Again, we are using special tokens (technically called parameters) to
// protect against SQL injection attacks.
$query = "
INSERT INTO users (
username,
password,
salt,
email
) VALUES (
:username,
:password,
:salt,
:email
)
";
// A salt is randomly generated here to protect again brute force attacks
// and rainbow table attacks. The following statement generates a hex
// representation of an 8 byte salt. Representing this in hex provides
// no additional security, but makes it easier for humans to read.
// For more information:
// http://en.wikipedia.org/wiki/Salt_%28cryptography%29
// http://en.wikipedia.org/wiki/Brute-force_attack
// http://en.wikipedia.org/wiki/Rainbow_table
$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
// This hashes the password with the salt so that it can be stored securely
// in your database. The output of this next statement is a 64 byte hex
// string representing the 32 byte sha256 hash of the password. The original
// password cannot be recovered from the hash. For more information:
// http://en.wikipedia.org/wiki/Cryptographic_hash_function
$password = hash('sha256', $_POST['password'] . $salt);
// Next we hash the hash value 65536 more times. The purpose of this is to
// protect against brute force attacks. Now an attacker must compute the hash 65537
// times for each guess they make against a password, whereas if the password
// were hashed only once the attacker would have been able to make 65537 different
// guesses in the same amount of time instead of only one.
for($round = 0; $round < 65536; $round++)
{
$password = hash('sha256', $password . $salt);
}
// Here we prepare our tokens for insertion into the SQL query. We do not
// store the original password; only the hashed version of it. We do store
// the salt (in its plaintext form; this is not a security risk).
$query_params = array(
':username' => $_POST['username'],
':password' => $password,
':salt' => $salt,
':email' => $_POST['email']
);
try
{
// Execute the query to create the user
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// This redirects the user back to the login page after they register
header("Location: login.php");
// Calling die or exit after performing a redirect using the header function
// is critical. The rest of your PHP script will continue to execute and
// will be sent to the user if you do not die or exit.
die("Redirecting to login.php");
}
?>
<h1>Register</h1>
<form action="signup.php" method="post">
Username:<br />
<input type="text" name="username" value="" />
<br /><br />
E-Mail:<br />
<input type="text" name="email" value="" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" />
<br /><br />
<input type="submit" value="Register" />
</form>
I have managed to narrow the problem down to:
$row = $stmt->fetch();
if($row)
{
// Using the password submitted by the user and the salt stored in the database,
// we now check to see whether the passwords match by hashing the submitted password
// and comparing it to the hashed version already stored in the database.
$check_password = hash('sha256', $_POST['password'] . $row['salt']);
for($round = 0; $round < 65536; $round++)
{
print("Checking password");
$check_password = hash('sha256', $check_password . $row['salt']);
}
if($check_password === $row['password'])
{
// If they do, then we flip this to true
$login_ok = true;
}
}
as the "print("checking password");" never happens. Can anyone spot a problem in the code? Thank you in advance for your help.
I realised what my problem was... I was attempting to login with the email instead of the username! Thank you all for your help.

PHP User/Admin Login using Database

The below code is used on my admin login page, which redirects to admin only page(s) upon a successful login. Via the database values, I need only users with an admin value of 1 to be granted access, while users with an admin value of 0 get prompted an error message similar to the "invalid username or password". Please signify placement of additional code.
Also, please keep in mind that I take code and patch together as best I can to work for me, so I'm not very fluent in php. Any help would be much appreciated.
DATABASE
ID Username Password Admin
1 John •••••• 0
2 Aaron •••••• 1
<?php
require("connect.php");
// Re-display the username if they fail to enter correct password.
$submitted_username = '';
// Determine whether the login form has been submitted
// If it has, run the login code, otherwise display form
if(!empty($_POST))
{
// Retrieve the users info from the database using username
$query = "
SELECT
id,
username,
password,
salt,
email,
admin
FROM users
WHERE
username = :username
";
// The parameter values
$query_params = array(
':username' => $_POST['username']
);
try
{
// Execute query against database
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
$login_ok = false;
// Retrieve user data from database. If $row is false, username in not registered
$row = $stmt->fetch();
if($row)
{
// Using the password submitted by the user and the salt stored in the database,
// we now check to see whether the passwords match by hashing the submitted password
// and comparing it to the hashed version already stored in the database.
$check_password = hash('sha256', $_POST['password'] . $row['salt']);
for($round = 0; $round < 65536; $round++)
{
$check_password = hash('sha256', $check_password . $row['salt']);
}
if($check_password === $row['password'])
{
// If they do, then we flip this to true
$login_ok = true;
}
}
// If the user logged in successfully, then we send them to the private members-only page
// Otherwise, we display a login failed message and show the login form again
if($login_ok)
{
// Here I am preparing to store the $row array into the $_SESSION by
// removing the salt and password values from it. Although $_SESSION is
// stored on the server-side, there is no reason to store sensitive values
// in it unless you have to. Thus, it is best practice to remove these
// sensitive values first.
unset($row['salt']);
unset($row['password']);
// This stores the user's data into the session at the index 'user'.
// We will check this index on the private members-only page to determine whether
// or not the user is logged in. We can also use it to retrieve
// the user's details.
$_SESSION['user'] = $row;
// Redirect the user to the private members-only page.
header("Location: index.php");
die("Redirecting to: index.php");
}
else {
// Tell the user they failed
$error = "Invalid Username or Password";
// Show them their username again so all they have to do is enter a new
// password. The use of htmlentities prevents XSS attacks. You should
// always use htmlentities on user submitted values before displaying them
// to any users (including the user that submitted them). For more information:
// http://en.wikipedia.org/wiki/XSS_attack
$submitted_username = htmlentities($_POST['username'], ENT_QUOTES, 'UTF-8');
}
}
?>
Maybe this will work :-
if($check_password === $row['password'] && $row['admin'] == 1)
{
$login_ok = 1;
}else
{
$login_ok = 0;
}
OR
You can change your query
$query = "
SELECT
id,
username,
password,
salt,
email,
admin
FROM users
WHERE
username = :username
admin = 1
";

Changing username form not working

I am new to PHP however when I am trying to create a change username form, I am just receiving an error.
"Failed to run query: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined"
I am not sure what is causing this error but I am only getting it when I add the username input form.
I have uploaded my edit_account and config file to pastebin for you all to look at.
Thanks in advanced
Unique
-------- Links --------
Common.php --> http://pastebin.com/zTHmef5V
edit_account.php --> http://pastebin.com/t8faiSyv
-------- Code --------
common.php:
<?php
// These variables define the connection information for your MySQL database
$username = "root";
$password = "";
$host = "localhost";
$dbname = "website";
// UTF-8 is a character encoding scheme that allows you to conveniently store
// a wide varienty of special characters, like ¢ or €, in your database.
// By passing the following $options array to the database connection code we
// are telling the MySQL server that we want to communicate with it using UTF-8
// See Wikipedia for more information on UTF-8:
// http://en.wikipedia.org/wiki/UTF-8
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');
// A try/catch statement is a common method of error handling in object oriented code.
// First, PHP executes the code within the try block. If at any time it encounters an
// error while executing that code, it stops immediately and jumps down to the
// catch block. For more detailed information on exceptions and try/catch blocks:
// http://us2.php.net/manual/en/language.exceptions.php
try
{
// This statement opens a connection to your database using the PDO library
// PDO is designed to provide a flexible interface between PHP and many
// different types of database servers. For more information on PDO:
// http://us2.php.net/manual/en/class.pdo.php
$db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options);
}
catch(PDOException $ex)
{
// If an error occurs while opening a connection to your database, it will
// be trapped here. The script will output an error and stop executing.
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code
// (like your database username and password).
die("Failed to connect to the database: " . $ex->getMessage());
}
// This statement configures PDO to throw an exception when it encounters
// an error. This allows us to use try/catch blocks to trap database errors.
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// This statement configures PDO to return database rows from your database using an associative
// array. This means the array will have string indexes, where the string value
// represents the name of the column in your database.
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
// This block of code is used to undo magic quotes. Magic quotes are a terrible
// feature that was removed from PHP as of PHP 5.4. However, older installations
// of PHP may still have magic quotes enabled and this code is necessary to
// prevent them from causing problems. For more information on magic quotes:
// http://php.net/manual/en/security.magicquotes.php
if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())
{
function undo_magic_quotes_gpc(&$array)
{
foreach($array as &$value)
{
if(is_array($value))
{
undo_magic_quotes_gpc($value);
}
else
{
$value = stripslashes($value);
}
}
}
undo_magic_quotes_gpc($_POST);
undo_magic_quotes_gpc($_GET);
undo_magic_quotes_gpc($_COOKIE);
}
// This tells the web browser that your content is encoded using UTF-8
// and that it should submit content back to you using UTF-8
header('Content-Type: text/html; charset=utf-8');
// This initializes a session. Sessions are used to store information about
// a visitor from one web page visit to the next. Unlike a cookie, the information is
// stored on the server-side and cannot be modified by the visitor. However,
// note that in most cases sessions do still use cookies and require the visitor
// to have cookies enabled. For more information about sessions:
// http://us.php.net/manual/en/book.session.php
session_start();
edit_account.php:
<?php
// First we execute our common code to connection to the database and start the session
$commonPath = $_SERVER['DOCUMENT_ROOT'];
$commonPath .= "/include/common.php";
require($commonPath);
// At the top of the page we check to see whether the user is logged in or not
if(empty($_SESSION['user']))
{
// If they are not, we redirect them to the login page.
header("Location: include/login.php");
// Remember that this die statement is absolutely critical. Without it,
// people can view your members-only content without logging in.
die("Redirecting to login.php");
}
// This if statement checks to determine whether the edit form has been submitted
// If it has, then the account updating code is run, otherwise the form is displayed
if(!empty($_POST))
{
// Make sure the user entered a valid E-Mail address
if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
{
die("Invalid E-Mail Address");
}
// If the user is changing their E-Mail address, we need to make sure that
// the new value does not conflict with a value that is already in the system.
// If the user is not changing their E-Mail address this check is not needed.
if($_POST['email'] != $_SESSION['user']['email'])
{
// Define our SQL query
$query = "
SELECT
1
FROM users
WHERE
email = :email
";
// Define our query parameter values
$query_params = array(
':email' => $_POST['email']
);
try
{
// Execute the query
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// Retrieve results (if any)
$row = $stmt->fetch();
if($row)
{
die("This E-Mail address is already in use");
}
}
if($_POST['username'] != $_SESSION['user']['username'])
{
// Define our SQL query
$query = "
SELECT
1
FROM users
WHERE
username = :username
";
// Define our query parameter values
$query_params = array(
':username' => $_POST['username']
);
try
{
// Execute the query
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// Retrieve results (if any)
$row = $stmt->fetch();
if($row)
{
die("This username is already in use");
}
}
// If the user entered a new password, we need to hash it and generate a fresh salt
// for good measure.
if(!empty($_POST['password']))
{
$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
$password = hash('sha256', $_POST['password'] . $salt);
for($round = 0; $round < 65536; $round++)
{
$password = hash('sha256', $password . $salt);
}
}
else
{
// If the user did not enter a new password we will not update their old one.
$password = null;
$salt = null;
}
// Initial query parameter values
$query_params = array(
':email' => $_POST['email'],
':user_id' => $_SESSION['user']['id'],
);
// If the user is changing their password, then we need parameter values
// for the new password hash and salt too.
if($password !== null)
{
$query_params[':password'] = $password;
$query_params[':salt'] = $salt;
}
// Note how this is only first half of the necessary update query. We will dynamically
// construct the rest of it depending on whether or not the user is changing
// their password.
$query = "
UPDATE users
SET
email = :email
";
$query = "
UPDATE users
SET
username = :username
";
// If the user is changing their password, then we extend the SQL query
// to include the password and salt columns and parameter tokens too.
if($password !== null)
{
$query .= "
, password = :password
, salt = :salt
";
}
// Finally we finish the update query by specifying that we only wish
// to update the one record with for the current user.
$query .= "
WHERE
id = :user_id
";
try
{
// Execute the query
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// Now that the user's E-Mail address has changed, the data stored in the $_SESSION
// array is stale; we need to update it so that it is accurate.
$_SESSION['user']['email'] = $_POST['email'];
$_SESSION['user']['username'] = $_POST['username'];
// This redirects the user back to the members-only page after they register
header("Location: include/private.php");
// Calling die or exit after performing a redirect using the header function
// is critical. The rest of your PHP script will continue to execute and
// will be sent to the user if you do not die or exit.
die("Redirecting to private.php");
}
edit_account.php form:
<?php
include ('include/header.php');
include ('include/slider.php'); ?>
<div id="edit-account">
<h1>Edit Account</h1>
<center>
<form action="edit_account.php" method="post">
Username:<br />
<b><?php echo htmlentities($_SESSION['user']['username'], ENT_QUOTES, 'UTF-8'); ?></b>
<br /><br />
Change Username:<br />
<input type="text" name="username" value="<?php echo htmlentities($_SESSION['user']['username'], ENT_QUOTES, 'UTF-8'); ?>" /><br />
E-Mail Address:<br />
<input type="text" name="email" value="<?php echo htmlentities($_SESSION['user']['email'], ENT_QUOTES, 'UTF-8'); ?>" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" /><br />
<i>(leave blank if you do not want to change your password)</i>
<br /><br />
<input type="submit" value="Submit Changes" />
</form>
</center>
</div>
<?php
include ('include/footer.php');
?>
Within the last part of the second code segment make the marked changes:
set the value for the parameter :username instead of :email.
remove the redundant first begin of the UPDATE statement.
So this should be:
// Initial query parameter values
$query_params = array(
':username' => $_POST['username'] // set the value for the parameter :username
// ':email' => $_POST['email'], // that's not needed here
':user_id' => $_SESSION['user']['id'],
);
// If the user is changing their password, then we need parameter values
// for the new password hash and salt too.
if($password !== null)
{
$query_params[':password'] = $password;
$query_params[':salt'] = $salt;
}
/* remove this section
// Note how this is only first half of the necessary update query. We will dynamically
// construct the rest of it depending on whether or not the user is changing
// their password.
$query = "
UPDATE users
SET
email = :email
";
// because you overwrite this in the next statement:
*/
$query = "
UPDATE users
SET
username = :username
";

Certain mysql column info wont display PHP

I have a PHP site that I made that has an option to edit your account. On the edit account page, I have the username, Real Name, email, and password displayed. Everything display's perfectly except for the real name, which comes up as a blank. It displays fine on my memberlist page.
Here is my code
<html>
<head>
<title>Site</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<?php
// First we execute our common code to connection to the database and start the session
require("common.php");
// At the top of the page we check to see whether the user is logged in or not
if(empty($_SESSION['user']))
{
// If they are not, we redirect them to the login page.
header("Location: login.php");
// Remember that this die statement is absolutely critical. Without it,
// people can view your members-only content without logging in.
die("Redirecting to login.php");
}
// This if statement checks to determine whether the edit form has been submitted
// If it has, then the account updating code is run, otherwise the form is displayed
if(!empty($_POST))
{
// Make sure the user entered a valid E-Mail address
if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
{
die("Invalid E-Mail Address");
}
// If the user is changing their E-Mail address, we need to make sure that
// the new value does not conflict with a value that is already in the system.
// If the user is not changing their E-Mail address this check is not needed.
if($_POST['email'] != $_SESSION['user']['email'])
{
// Define our SQL query
$query = "
SELECT
1
FROM users
WHERE
email = :email
";
// Define our query parameter values
$query_params = array(
':email' => $_POST['email']
);
try
{
// Execute the query
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// Retrieve results (if any)
$row = $stmt->fetch();
if($row)
{
die("This E-Mail address is already in use");
}
}
// If the user entered a new password, we need to hash it and generate a fresh salt
// for good measure.
if(!empty($_POST['password']))
{
$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
$password = hash('sha256', $_POST['password'] . $salt);
for($round = 0; $round < 65536; $round++)
{
$password = hash('sha256', $password . $salt);
}
}
else
{
// If the user did not enter a new password we will not update their old one.
$password = null;
$salt = null;
}
// Initial query parameter values
$query_params = array(
':email' => $_POST['email'],
':user_id' => $_SESSION['user']['id'],
);
// If the user is changing their password, then we need parameter values
// for the new password hash and salt too.
if($password !== null)
{
$query_params[':password'] = $password;
$query_params[':salt'] = $salt;
}
// Note how this is only first half of the necessary update query. We will dynamically
// construct the rest of it depending on whether or not the user is changing
// their password.
$query = "
UPDATE users
SET
email = :email
";
// If the user is changing their password, then we extend the SQL query
// to include the password and salt columns and parameter tokens too.
if($password !== null)
{
$query .= "
, password = :password
, salt = :salt
";
}
// Finally we finish the update query by specifying that we only wish
// to update the one record with for the current user.
$query .= "
WHERE
id = :user_id
";
try
{
// Execute the query
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// Now that the user's E-Mail address has changed, the data stored in the $_SESSION
// array is stale; we need to update it so that it is accurate.
$_SESSION['user']['email'] = $_POST['email'];
// This redirects the user back to the members-only page after they register
header("Location: private.php");
// Calling die or exit after performing a redirect using the header function
// is critical. The rest of your PHP script will continue to execute and
// will be sent to the user if you do not die or exit.
die("Redirecting to private.php");
}
?>
<h1>Edit Account</h1>
<div class="body">
<form action="edit_account.php" method="post">
Name:<br />
<b><?php echo htmlentities($_SESSION['user']['name'], ENT_QUOTES, 'UTF-8'); ?>
</b>
<br><br>
Username:<br />
<b><?php echo htmlentities($_SESSION['user']['username'], ENT_QUOTES, 'UTF-8'); ?></b>
<br /><br />
E-Mail Address:<br />
<input type="text" name="email" value="<?php echo htmlentities($_SESSION['user']
['email'], ENT_QUOTES, 'UTF-8'); ?>" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" /><br />
<i>(leave blank if you do not want to change your password)</i>
<br /><br />
<input type="submit" value="Update Account" />
</form>
</div>
</body>
</html>

Categories