The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> PHP Development
> PHP FAQs and Stickies
|
Page 7 -
How to program a basic but secure login system using PHP and MySQL
Page 7 - Discuss How to program a basic but secure login system using PHP and MySQL in the PHP FAQs and Stickies forum on Dev Shed. How to program a basic but secure login system using PHP and MySQL Look here for FAQ's and stickies on common PHP questions.
|
|
 |
|
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

March 11th, 2013, 08:32 AM
|
 |
pollyanna
|
|
Join Date: Jul 2012
Location: Germany
|
|
Letting the client hash the password does have an impact on security: It completely voids the purpose of the hash. You're back to "good" ol' plaintext passwords: The user sends you a string, which you compare to the entry in your database. If both match, you let the user in, otherwise you don't. In other words, the hash now is the password. The hashing merely serves as a kind of "password generation" process -- and you cannot even tell if the JavaScript code was ever actually executed.
I think there's a fundamental misunderstanding: You need the original password. You have to know it in order to hash it and compare the result with the hash in your database. You cannot leave the hashing to your user. If you do, this reduces the whole process to absurdity.
There's a golden rule of security: Don't roll your own. Don't invent your own security protocols, encryption algorithms or whatever. The reason is that as a layman (which we all are), you're guaranteed to make some stupid mistake somewhere. This client-side hashing is a good example for that: It may sound like a good idea at first. At least you wouldn't think it makes a big difference. But it completely breaks the whole process.
So whenever you find yourself fumbling with your own JavaScript security algorithms, stop right there. You're totally on the wrong track. When you got a problem, always look for the standard solution. In this case it's the already mentioned TLS protocol.
By the way, there is in fact a standard solution to the problem of always having to transmit the password: public-key authentication. The SSH protocol uses this, for example. However, it's currently not an options for stardard websites (and probably won't be for a long time). And it doesn't solve your actual problem, anyway.
|

March 12th, 2013, 09:12 AM
|
|
Registered User
|
|
Join Date: Mar 2013
Posts: 6
Time spent in forums: 1 h 26 m 59 sec
Reputation Power: 0
|
|
Thanks all for you answers
Will see how to use https
|

March 13th, 2013, 10:21 AM
|
|
Contributing User
|
|
Join Date: Nov 2012
Posts: 56
Time spent in forums: 13 h 10 m 2 sec
Reputation Power: 1
|
|
|
Hi E-Oreo,
I must thank you for this very important login script, especially that it is the only most secure login code I have come across after along time searching the internet for a tutorial such as yours.
How I wish you could expand it further to user levels.
Thanks again and stay well.
Joseph
|

March 13th, 2013, 10:40 AM
|
|
Registered User
|
|
Join Date: Mar 2013
Posts: 6
Time spent in forums: 1 h 26 m 59 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by Jacques1 Letting the client hash the password does have an impact on security: It completely voids the purpose of the hash. |
I undersand all you have said
But per example if I use wireshark in SMF 2.0.4 login I found(I changed my hash):
user=metRo_&passwrd=&hash_passwrd=3eb4c56d121122b25e88cc0a11b0f123a6bcaa2
Is it insecure?
|

March 13th, 2013, 11:42 AM
|
 |
pollyanna
|
|
Join Date: Jul 2012
Location: Germany
|
|
|
I think you completely misunderstood what I said.
I said that you must not do the hashing client-side. This is worse than sending the original password.
Sending the hashed password instead of the original password is no improvement in any way. The hash now is is the password. It is the secret used to authenticate the member -- which is the very definition of a password.
You see the problem? Let's say I've made up the password "secret123". Your login form transforms that into some hash "d41d8cd98f00b204e9800998ecf8427e" and sends the hash instead of the original password. This means that the hash is the actual password; the original string "secret123" is just some kind of "internal password". An attacker doesn't need to know this internal password, all he/she needs is the hash. Because that's what's used to authenticate at your server.
In other words, sending the hashed password in your system is exactly equivalent to sending the plaintext password in a classical system. It is in fact the plaintext password. The only difference is that it has been derived from the original password chosen by the user.
What's worse about your system is that your server will also store the original password or the hash (there's no difference). In other words, your database holds the plaintext passwords of your users. This is widely considered a gigantic security hole, because anybody with access to the database can see all passwords and (mis-)use them.
I don't even understand why you keep fumbling with the login system. Both E-Oreo and I have clearly said that the solution to your problem is encryption via SSL. This and nothing else will solve the problem of being able to read the network traffic.
You can hash or encrypt the password in any way you want -- when it's send through an unencrypted connection, anybody can fetch and use it.
|

March 14th, 2013, 02:28 AM
|
|
Contributing User
|
|
Join Date: Nov 2012
Posts: 56
Time spent in forums: 13 h 10 m 2 sec
Reputation Power: 1
|
|
Hi,
I want to include gallery.php as a default page which will have a link to the login page to access the members only page gallery_sec.php. And when user logs out should be redirected to the gallery page.
Here is what I have done so far. In the login.php, I changed to:
PHP Code:
// Redirect the user to the private members-only page.
header("Location: gallery_sec.php");
die("Redirecting to: gallery_sec.php");
In the gallery_sec.php:
PHP Code:
<?php
// First we execute our common code to connection to the database and start the session
require("admin/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: gallery.php");
// Remember that this die statement is absolutely critical. Without it,
// people can view your members-only content without logging in.
die("Redirecting to gallery.php");
}
// Everything below this point in the file is secured by the login system
// We can display the user's username to them by reading it from the session array. Remember that because
// a username is user submitted content we must use htmlentities on it before displaying it to the user.
?>
And on the login.php:
PHP Code:
<?php
// First we execute our common code to connection to the database and start the session
require("admin/common.php");
// We remove the user's data from the session
unset($_SESSION['user']);
// We redirect them to the login page
header("Location: login.php");
die("Redirecting to: login.php");
?>
Unfortunately, each time I open the browser the first page to load is still login.php instead of the gallery.php, which is also set to be a default index page in on the server. And again when I logout I am taken to the login page instead of the gallery.php.
I want to be taken to the login page only if i click a button on the gallery.php. In short I have two types of users: guest and registered.
I need help, please.
joseph
|

March 18th, 2013, 11:28 PM
|
|
Registered User
|
|
Join Date: Feb 2013
Posts: 6
Time spent in forums: 3 h 18 m
Reputation Power: 0
|
|
I am using my login within an iframe and when login success it opens header tag in _top rather than in the iframe (which i want).
Although I have just discovered that when the user types the wrong details the login shows _top also (which i don't want) so i have edited the code again and added 4 parts of code rather than using _top as original target for form
I would like to be able to do this so if the user types wrong login details it stays within the iframe if correct it opens the header _top i have tried inserting 4 bits of code which i thought may work but unsuccessful
below is my Login.php code (the parts in bold are the code i thought may work i am fairly new to php and just experimenting
Can somebody help me please to get this working how i would like it to
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 = '';
$errors = '';
PHP Code:
// 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,
nivel,
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++)
{
$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;
Code:
//Login ok so post target = _top
$poststring= '_top';
PHP Code:
}
}
// 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 and check user level.
if($_SESSION['user']['nivel'] == '1')
{
header("Location: index.php");
die("Redirecting to: index.php");
}
if($_SESSION['user']['nivel'] == '2')
{
header("Location: index2.php");
die("Redirecting to: index2.php");
}
}
else
{
Code:
//Login not successful so post target = _self
$poststring= '_self';
PHP Code:
// Tell the user they failed
$errors= "Invalid Login Details";
// 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:
// (url)
$submitted_username = htmlentities($_POST['username'], ENT_QUOTES, 'UTF-8');
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "(url)">
<html xmlns="(url)">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Login</title>
<link href="../Css/login.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="centrepage">
<div id="login">
<form name="login" id="loginform" action="login.php" target="
Code:
<?php $poststring;?>(just get both within the iframe) Also tried <?php echo '$poststring'; (but just get both in a new tab)?>
PHP Code:
" method="post">
<p>
Username<br />
<input name="username" id="username" type="text" size="19" value="<?php echo $submitted_username; ?>"/>
<br />
Password<br />
<input name="password" id="password" type="password" value="" size="20"/>
</p>
<div id="status" >
<?php echo $errors;?>
</div>
<input type="submit" id="loginbtn" value="Login" />
</form>
</div>
</div>
</body>
</html>
Last edited by ricp24 : March 19th, 2013 at 10:01 PM.
Reason: More Detail Added
|

March 19th, 2013, 08:54 AM
|
|
Registered User
|
|
Join Date: Mar 2013
Posts: 6
Time spent in forums: 1 h 26 m 59 sec
Reputation Power: 0
|
|
In my website I'm using a menu based in javascript. What I want to know is how to tun this code:
PHP Code:
if(empty($_SESSION['user']))
{
header("Location: index.php");
die("Redirecting to index.php");
}
every time the user click the button and change the div he is seeing.
Per example I enter the site and login. After I open the site in another tab. I logout in the first tab I still can navigate in the second tab while I don't open a page with the php code above.
thanks
|

March 19th, 2013, 11:03 PM
|
 |
Lost in code
|
|
|
|
Quote: | Unfortunately, each time I open the browser the first page to load is still login.php instead of the gallery.php, which is also set to be a default index page in on the server. And again when I logout I am taken to the login page instead of the gallery.php. |
Are you typing the address to gallery.php and it's redirecting you to login.php? If that's the case then there must be some code running on gallery.php that is causing the redirect.
Did you update the logout page to return the user to gallery.php after they log out?
Quote: I would like to be able to do this so if the user types wrong login details it stays within the iframe if correct it opens the header _top i have tried inserting 4 bits of code which i thought may work but unsuccessful
below is my Login.php code (the parts in bold are the code i thought may work i am fairly new to php and just experimenting |
There is a timing problem here. You have to define target before the user logs in; obviously, at that point you don't know whether or not they are going to be successful.
If you want to change the URL of the frame parent page after login you should use JavaScript to do it. You can place this on the login.php page, after they successfully log in. Setting it in the form tag won't work.
Quote: | Per example I enter the site and login. After I open the site in another tab. I logout in the first tab I still can navigate in the second tab while I don't open a page with the php code above. |
You can only run PHP code when making a request to the server.
If you load your tab contents using AJAX, then you can put login checking code in whatever pages return the tab contents in response to the AJAX call. However, note that a header redirect in an AJAX call will not redirect the user's browser page; you have to use JavaScript to do that.
If you preload all of the tabs when the page is initially loaded, then the only way to do this would be to run an AJAX call to the server when they switch tabs just for the sole purpose of checking whether or not they are still logged in. If they are not, then you need to use JavaScript to redirect them back to the login page.
Last edited by E-Oreo : March 19th, 2013 at 11:09 PM.
|

March 20th, 2013, 04:40 PM
|
|
Registered User
|
|
Join Date: Feb 2013
Posts: 6
Time spent in forums: 3 h 18 m
Reputation Power: 0
|
|
Quote: | Originally Posted by E-Oreo If you want to change the URL of the frame parent page after login you should use JavaScript to do it. You can place this on the login.php page, after they successfully log in. Setting it in the form tag won't work. |
Many thanks for your help I have done this using
PHP Code:
if($_SESSION['user']['nivel'] == '1')
{
echo("<script language=\"javascript\">");
echo("top.location.href = \"index.php\";");
echo("</script>");
die("Redirecting to: index.php");
}
if($_SESSION['user']['nivel'] == '2')
{
echo("<script language=\"javascript\">");
echo("top.location.href = \"index2.php\";");
echo("</script>");
die("Redirecting to: index2.php");
}
}
And works just how I wanted it to but the only problem now is just before it redirects to the page chosen by user level a white flash appears is there a way I can get rid of this?
|

March 22nd, 2013, 11:51 AM
|
|
Contributing User
|
|
Join Date: Jul 2006
Posts: 65
Time spent in forums: 2 Days 15 h 21 m 26 sec
Reputation Power: 7
|
|
|
Notice: Undefined index: firstname
Hi
anyone have any idea why im getting Notice: Undefined index: firstname? what i've done was changed username to firstname shown below i also added firstname to users in my database any help would be great thanks.
original code from private.php:
PHP Code:
Hello <?php echo htmlentities($_SESSION['user']['username'], ENT_QUOTES, 'UTF-8'); ?>, secret content!<br />
code with firstname:
PHP Code:
Hello <?php echo htmlentities($_SESSION['user']['firstname'], ENT_QUOTES, 'UTF-8'); ?>, secret content!<br />
|

March 29th, 2013, 04:42 AM
|
|
Registered User
|
|
Join Date: Mar 2013
Posts: 1
Time spent in forums: 31 m 43 sec
Reputation Power: 0
|
|
|
forgot password
Could someone add "forgot password" script?
|

April 1st, 2013, 10:07 AM
|
 |
Likely to be eaten by a grue.
|
|
Join Date: Oct 2006
Location: Pennsylvania, USA
|
|
Quote: | Originally Posted by YCPC55 Hi
anyone have any idea why im getting Notice: Undefined index: firstname? what i've done was changed username to firstname shown below i also added firstname to users in my database any help would be great thanks.
original code from private.php:
PHP Code:
Hello <?php echo htmlentities($_SESSION['user']['username'], ENT_QUOTES, 'UTF-8'); ?>, secret content!<br />
code with firstname:
PHP Code:
Hello <?php echo htmlentities($_SESSION['user']['firstname'], ENT_QUOTES, 'UTF-8'); ?>, secret content!<br />
| Err...because the original code didn't include firstname? Did you add firstname to the session?
__________________
HEY! YOU! Read the New User Guide and Forum Rules
"They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin
"The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002
Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
|

April 1st, 2013, 10:58 AM
|
 |
Likely to be eaten by a grue.
|
|
Join Date: Oct 2006
Location: Pennsylvania, USA
|
|
Unnecessary conversation about RSA split and moved here. Move along.
|

April 2nd, 2013, 05:18 AM
|
|
Registered User
|
|
Join Date: Apr 2013
Posts: 5
Time spent in forums: 1 h 16 m 52 sec
Reputation Power: 0
|
|
|
Issue with header redirect
E-Oreo,
Firstly, thank you for sharing this script with everyone, it's definitely helpful and appreciated! I'm experiencing an issue, which I don't know how to fix, and I hope you or anyone else on this forum might have an answer for. Given that common.php sets the session and header info, when I'm redirecting users from one page to another, I get an error "Cannot modify header information - headers already sent by..." and the reference is common.php on line 78.
I want login.php to be the first page which visitors see, with a "Register" link at the bottom of the form for anyone who's new to the website. Clicking on it would take them to register.php, which according to the script will then redirect them back to login.php.
I tried using header_remove(); between redirects, but that didn't help either.
Any help would be greatly appreciated! Thanks in advance.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|