TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   Absolute Beginners (http://www.talkphp.com/absolute-beginners/)
-   -   First Login Script (http://www.talkphp.com/absolute-beginners/2244-first-login-script.html)

StevenF 02-13-2008 06:43 PM

First Login Script
 
Hello,

I've created a little project for myself to improve my PHP. I've decided to create a website which uses a login script. I need to allow new users to register and existing users to login.

So far I have the register page working: It's a form with a Username, email and password field and the details entered are entered into the database.

I'm unsure how to do the login page :-( I need to do something like:
  • Search database for matching username
  • Search database for matching password
  • If both of the above match, then login and go to <insert page>

I don't really know how to do this. I was wondering if someone could point me in the right direction?

Thanks,
Steven

webtuto 02-13-2008 07:56 PM

ok here is the code

PHP Code:

$sql "select * from `admin` where name='$_POST[name]' and pass='$_POST[pass]'";
$res=mysql_query($sql);
$count mysql_num_rows($res);
if(
$count == 1){
header("Location: admin.php");
}else{
 echo
"<center><h2>The username or password are mistaken please check theme again<h2>";



SOCK 02-13-2008 08:01 PM

Quote:

Originally Posted by StevenF (Post 10682)
I need to do something like:
  • Search database for matching username
  • Search database for matching password
  • If both of the above match, then login and go to <insert page>

Yes, yes & yes. ;-)

Retrieve the values via POST from the login form, validate (check that they're strings, length, etc if you want to), escape (using mysql_real_escape_string() for example, if working in MySQL) and then check against the values in the database, e.g.
PHP Code:

// $uname is our username value / $upass is the password
// validated & escaped at this point, if not, redirect to login
$sql'SELECT userID, COUNT(*) FROM users WHERE ';
$sql.= "username = '{$uname}' AND userpass = '{$upass}'";

if ( 
mysql_resultmysql_query($sql), 0) !== ) {
    
// no login
    // redirect to login form, show error message
} else {
    
// login process
    // recommend creating a unique token to store for this login
    // set in the `users` table or a second `logins` table
    // set session data (usually userID value, unique token)
    // redirect to index


Extremely glib example, take it for what it's worth. I usually have a second `logins` table (as noted in the comments) that stores the `userID` value, the session_id() value, a unique token, etc. to match against each subsequent page request to make sure the user is valid.

Check the PHP manual entries for function definitions.

SOCK 02-13-2008 08:03 PM

Quote:

Originally Posted by webtuto (Post 10684)
PHP Code:

$sql "select * from `admin` where name='$_POST[name]' and pass='$_POST[pass]'"


Never a good idea to allow POST data to directly interface with your database. Please be careful about passing bad code to new users!!

Google search : SQL injection

Rendair 02-13-2008 08:11 PM

I would also say encrypt any passwords before putting them in the database and like SOCK said do some prevention of mysql injections.

SOCK 02-13-2008 10:19 PM

In revisiting this thread, it occurred to me to pass some additional advice (as per Rendair's comment on encrypting or hashing the password). Most of these things I take for granted and forget to mention. At any rate, here are other notes / tips in no specific order-
  • Try to keep the login process simple, don't add anything that will hang you up later.
  • Make sure you store the password as a hashed value, minimum MD5, SHA1 / SHA256 recommended. Do NOT use the database 'Password()' function to hash the password. It's not portable and I don't trust it. MD5 and SHA1 are both innate PHP / MySQL functions. You'll want to find a class or use PHP's mhash functions for anything stronger.
  • Store ONLY non-critical information in the session, e.g. the userID value or the unique token to match against a `logins` table.
  • DO use session_regenerate_id() on each successful login check, e.g. each page request that checks against valid session data. Once the user is validated against the session / `logins` table, then regenerate the session_id and restore the data.
  • Consider creating a 'remember me' cookie so the user can automagically log back in after closing the browser.
  • Consider using a `registrationID` column in the database to match against to help root out spammers (in other words, once they've registered, have an email sent to them that will have a link matching their `registrationID` column value).
  • DO NOT allow any database errors to show, e.g. using mysql_error() to send an error message back to the user on a non-login or an error. This is what SQL injection attackers look for. Trap all errors in a log if need be. Shut off the PHP ini display_errors setting.

Then create a cool web 2.0ish design wrapped around all that, maybe implement an XHR (Ajax) request for the login process, etc.

Once you've got it all done, trash it all and redo it as in OOP. ;-)

StevenF 02-13-2008 10:24 PM

Thanks everyone, I really appreciate all of your help! I'm going to give it a shot just now.

SOCK - Thanks for that. A lot of it doesn't make much sense and I don't know how to do. I have however stored the password in encripted md5, I just found out about that today.

Can I ask what UserID is? Is it an auto number field given to each user?

Thanks
Steven

SOCK 02-13-2008 10:50 PM

Quote:

Originally Posted by StevenF (Post 10699)
Can I ask what UserID is? Is it an auto number field given to each user?

Yes; in my table designs I will often use an AUTO_INCREMENT INT value as the PRIMARY KEY to link tables on. So each user has a `userID` field that is the most basic, simple method to refer to that user, regardless of how many columns and how much data is stored in them. Link it in the session data and the `logins` table if you are so inclined to add one. No need to store the username or any other data if you simply store the `userID`.

SOCK 02-13-2008 11:00 PM

Something else to consider when designing the `user` table, make sure you use a UNIQUE index on the `username` column - keep people from registering the same name, and makes the logic simple when registering users.

StevenF 02-13-2008 11:44 PM

My eyes are getting tired, so I'm going to leave it for today. I've suddenly gotten a strange error:

Quote:

MySQL Error:'.mysql_error()); mysql_select_db($database) or die ('MySQL Error:'.mysql_error()); //setting variables $reg_username = addslashes($_POST['reg_username']); $reg_email = addslashes($_POST['reg_email']); $reg_password = md5($_POST['reg_password']); //creating a query that inserts the data into the database $query = 'INSERT INTO users SET user_name = "'.mysql_real_escape_string($reg_username).'", email = "'.mysql_real_escape_string($reg_email).'", user_pass = "'.mysql_real_escape_string($reg_password).'"' ; //execcute a query on a MySQL database mysql_query($query); //close database connection mysql_close(); ?>
I don't know what's causing it, it was working fine. Here's the code bellow: (the database is called scotlandbands).

Code:

        //Database Structute
                //Setting username and password
                $username = '';
                $password = '';
                $database = "scotlandbands";
               
        //MySQL Connections
        mysql_connect($localhost, $username, $password) or die ('<strong>MySQL Error:</strong>'.mysql_error());
        mysql_select_db($database) or die ('<strong>MySQL Error:</strong>'.mysql_error());
       
        //setting variables
        $reg_username = addslashes($_POST['reg_username']);
        $reg_email = addslashes($_POST['reg_email']);
        $reg_password = md5($_POST['reg_password']);
       
        //creating a query that inserts the data into the database
        $query = 'INSERT INTO users SET

          user_name = "'.mysql_real_escape_string($reg_username).'",
          email = "'.mysql_real_escape_string($reg_email).'",
          user_pass = "'.mysql_real_escape_string($reg_password).'"';
       
        //execcute a query on a MySQL database
        mysql_query($query);
       
        //close database connection
        mysql_close();


SOCK 02-14-2008 12:28 AM

Ok, the error message is really odd. It almost looks like the httpd server isn't parsing PHP correctly and instead outputting all your PHP code. It seems as if it begins with the call to mysql_connect() but I don't see why.

Have you been successfully connecting to MySQL from this or another PHP script? Does this script have the .php extension (or the appropriate extension to parse PHP)?

Please use the provided PHP code tags when posting, it makes it much easier to spot errors, e.g.
PHP Code:

$variable 'something'

Something else in your code important to mention; you're using addslashes() and mysql_real_escape_string(). Bad combination. You're going to get slashes upon slashes in your stored data. Not to mention if you have magic_quotes turned "On" as well, you'll have three sets of slashes. It can get intense.

Make sure magic_quotes is turned "Off", and use mysql_real_escape_string() only.

StevenF 02-14-2008 12:42 AM

I don't know what was wrong there, but I seemed to have fixed it! :-P

I didn't know that addslashes and mysql_real_escape_string() weren't to be used together. Thanks for letting me know!

I am getting somewhere now, I have the following:
Code:

<?php

        //Database Structure
                //Setting username and password

                $username="";
                $password="";
                $database="scotlandbands";

                mysql_connect($localhost, $username, $password) or die ('<strong>MySQL Error:</strong>'.mysql_error());
                mysql_select_db($database) or die ('<strong>MySQL Error:</strong>'.mysql_error());
               
       
        //setting variables
        $reg_username = ($_POST['reg_username']);
        $reg_email = ($_POST['reg_email']);
        $reg_password = md5($_POST['reg_password']);
       
        //creating a query that inserts the data into the database
        $query = 'INSERT INTO users SET                user_name = "'.mysql_real_escape_string($reg_username).'",
                                                                                email = "'.mysql_real_escape_string($reg_email).'",
                                                                                user_pass = "'.mysql_real_escape_string($reg_password).'"';
       
        //execcute a query on a MySQL database
        mysql_query($query);
       
        //close database connection
        mysql_close();

?>

Hope that's more readable now!

Now, when I try to enter a username and password which is stored in the database, I'm being taken to login.html - which means the login was not successful. I don't know why this is happening, because I'm entering the correct details.

SOCK 02-14-2008 01:19 AM

Quote:

Originally Posted by StevenF (Post 10713)
Now, when I try to enter a username and password which is stored in the database, I'm being taken to login.html - which means the login was not successful. I don't know why this is happening, because I'm entering the correct details.

Obviously what you've posted isn't your login script; can you show us that?

Alan @ CIT 02-14-2008 01:26 AM

Tip: you can use the [ php ][ /php ] tags to save having to manually color your code when posting :-)

The query in the script you posted is in the wrong format. You have mixed up INSERT and UPDATE syntax.

An INSERT query should look something like:

PHP Code:

$query "INSERT INTO table (column1, column2, etc) VALUES ('value1', 'value2', 'etc')" 

An UPDATE query should look something like:

PHP Code:

$query "UPDATE table SET column1 = 'value1, column2 = 'value2, etc = 'etc' WHERE something = 'else'" 

Alan

SOCK 02-14-2008 01:33 AM

Alan@CIT> Not to nitpick, but that INSERT format is perfectly fine. You just don't see it as often as the (column list) VALUES (data list) format.

MySQL Manual : INSERT syntax

Alan @ CIT 02-14-2008 07:45 AM

Ahh, cool - never knew you could do that :-)

Alan

StevenF 02-14-2008 09:47 AM

Quote:

Originally Posted by SOCK (Post 10726)
Obviously what you've posted isn't your login script; can you show us that?

See, I told you I was tired. :-D I posted the register script by mistake.

PHP Code:

<?php

    
//Database Structure
        //Setting username and password
        
$username="";
        
$password="";
        
$database="scotlandbands";

        
mysql_connect($localhost$username$password) or die ('<strong>MySQL Error:</strong>'.mysql_error());
        
mysql_select_db($database) or die ('<strong>MySQL Error:</strong>'.mysql_error());
        
        
//Setting variables from form data
        
$user $_POST['check_username'];
        
$pass $_POST['check_password'];
        
$login $_POST['login'];
        
        
$get mysql_query("SELECT count(userID) FROM users WHERE user_name = '$user' AND user_pass = '$pass'");
        
$result mysql_result($get,0);
        
        
mysql_close();
        
        
//Determine if there is a result
        
if ($result != 1header ("Location: login.html");
        else {
            
header ("Location: index.html");
            
$_SESSION['user_name'] = $user;
            };
            
            
?>

I'm getting somewhere now: If I take out the md5 encryption, and register a username and password, I can use that to log in. But, when I try it with md5 encryption, I can't login! Do I have to decrypt it or something?

This is how I'm using md5:

PHP Code:

$reg_password md5($_POST['reg_password']); 


SOCK 02-14-2008 03:22 PM

Quote:

Originally Posted by StevenF (Post 10742)
PHP Code:

<?php
//Setting variables from form data
$user $_POST['check_username'];
$pass $_POST['check_password'];
$login $_POST['login'];
        
$get mysql_query("SELECT count(userID) FROM users WHERE user_name = '$user' AND user_pass = '$pass'");

I'm getting somewhere now: If I take out the md5 encryption, and register a username and password, I can use that to log in. But, when I try it with md5 encryption, I can't login! Do I have to decrypt it or something?

No, but you do have to compare an MD5 hashed value with another MD5 hashed value. You need to either hash the $pass value again prior to the query, or hash it within the query, e.g.
PHP Code:

// use $md5pass in your query instead of $pass
$md5passmd5($_POST['check_password']); 

-- or --
Code:

SELECT COUNT(userID)
FROM users
WHERE user_name = 'username'
AND user_pass = MD5('userpass');

Because MD5() is also a MySQL function, you can do it straight in the query. Just make sure not to hash the password in PHP and then attempt to hash it again!

Quote:

Originally Posted by StevenF (Post 10742)
PHP Code:

//Determine if there is a result
if ($result != 1header ("Location: login.html");
else {
    
header ("Location: index.html");
    
$_SESSION['user_name'] = $user;
}; 


A couple of comments here on the above code.
  • That last line uses a semicolon to end the if-else block. Not sure if that's even legal. At any rate, unnecessary.
  • Don't assign session data after the call to header().
  • Try not to mix statement styles, i.e. use a single indented line after the if conditional, then use braces after the else statement. Assume you'll want to have more than one statement after the if and use braces. Be uniform in your code structure. It makes it much easier to read and troubleshoot. Once in awhile I'll use syntax like that, but it's a one-liner only.

SOCK 02-14-2008 07:57 PM

PHP Code:

//setting variables 
$reg_username = ($_POST['reg_username']);
$reg_email = ($_POST['reg_email']);
$reg_password md5($_POST['reg_password']);
    
//creating a query that inserts the data into the database
$query 'INSERT INTO users SET
    user_name = "'
.mysql_real_escape_string($reg_username).'",
    email = "'
.mysql_real_escape_string($reg_email).'",
    user_pass = "'
.mysql_real_escape_string($reg_password).'"
'


As I was reading over this thread yet again, I suddenly noticed this code (probably because most of it was hidden unless you scroll over a bit). That's not quite what you want. You mentioned having trouble matching against the password, and here's another thing to consider. You're actually running mysql_real_escape_string() on an MD5 hash value, the value stored in $reg_password. So basically, it might be a completely invalid string stored in the database as compared to what you're trying to input.

This is what you want to do instead, on both the registration form and the login processing form:
PHP Code:

// escape the input string
$reg_passmysql_real_escape_string($_POST['reg_password']);
// now run md5 on it
$md5passmd5($reg_pass); 

...which is different than doing
PHP Code:

// running the hash function on an unchecked, unescaped string!
$reg_passmd5($_POST['reg_password']);
// INSERT INTO ... mysql_real_escape_string($reg_pass) 

Now here's the twist. Technically speaking you can always omit the use of m_r_e_s() on the password field, since you're going to run MD5 on it anyway. If you look at it that way, regardless of what the input value is going to be, all the database is going to see is a 32 character hash value. See what I'm saying?

The other thing you want to look at redoing is the reassignment code. All this
PHP Code:

$somevariable $_POST['somevariable']; 

..is all unnecessary and takes up resources. If you must reassign the variables, at least reassign the output of mysql_real_escape_string() to them.

ReSpawN 02-14-2008 08:01 PM

Quote:

Originally Posted by SOCK (Post 10731)
Alan@CIT> Not to nitpick, but that INSERT format is perfectly fine. You just don't see it as often as the (column list) VALUES (data list) format.

MySQL Manual : INSERT syntax

Not to go off topic and or anything but the SET command works better for some people. Thanks for the INSERT documentation SOCK.


All times are GMT. The time now is 08:06 AM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0