Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    Senior Coder Rowsdower!'s Avatar
    Join Date
    Oct 2008
    Location
    Some say it's everything.
    Posts
    2,027
    Thanks
    5
    Thanked 397 Times in 390 Posts

    Secure PHP Login - I Need a How-To for a Beginner

    I just got my first account with PHP/MySQL access so I am just starting my voyage into this new world. My usual method to learning anything is to get in over my head and try to struggle into understanding. It usually works pretty well but I need working examples to play with. The PHP/MySQL process has been no different so here's what I'm trying to figure out...

    I first got my feet wet with basic syntax for echos, arrays, etc. Then I moved on to a VERY basic login structure (using this tutorial: http://www.phpeasystep.com/workshopview.php?id=6). I made my very first MySQL databse successfully and got the PHP to work with it. Existing logins were accepted and others were given a failed login notice. So far so good. The HTML doesn't validate but that's just because it's a quick and dirty page to test PHP functionality. (http://rowsdower.freehostia.com/ user name "test" password "test")

    The wimpy, basic version I have implemented does not use sessions/cookies and does not check to see if a user is logged in before showing the content of the destination page. Part of it looks like it's supposed to, but there are no provisions to actually start a session that I can see. I would guess that this would require another row in the database to store whether or not a session is in progress or else to store some type of cookie data. Is this correct?

    Anyway, as a result of the weakness in this setup anyone can navigate directly to the URL if they are able to guess at it.

    The basic structure and flow from document to document during the login procedure is index.php --> checklogin.php --> login_success.php
    Here is the code I have used in each case...

    index.php:
    PHP Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <
    html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <
    head>
    <
    title>My First PHP :)</title>
    <
    meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    </
    head>
    <
    body>
    <
    div>
    <
    span>The Junior method:</span>
    <
    table width="300" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC"
    <
    tr
    <
    form name="form1" method="post" action="checklogin.php"
    <
    td
    <
    table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF"
    <
    tr
    <
    td colspan="3"><strong>Member Login </strong></td
    </
    tr
    <
    tr
    <
    td width="78">Username</td
    <
    td width="6">:</td
    <
    td width="294"><input name="myusername" type="text" id="myusername"></td
    </
    tr
    <
    tr
    <
    td>Password</td
    <
    td>:</td
    <
    td><input name="mypassword" type="password" id="mypassword"></td
    </
    tr
    <
    tr
    <
    td>&nbsp;</td
    <
    td>&nbsp;</td
    <
    td><input type="submit" name="Submit" value="Login"></td
    </
    tr
    </
    table
    </
    td
    </
    form
    </
    tr
    </
    table


    </
    div
    </
    body
    </
    html
    checklogin.php:
    PHP Code:
    <?php
    $host
    ="mysql4.freehostia.com"// Host name 
    $username="<whatever>"// Mysql username 
    $password="<whatever>"// Mysql password 
    $db_name="<whatever>"// Database name 
    $tbl_name="<whatever>"// Table name 

    // Connect to server and select databse.
    mysql_connect("$host""$username""$password")or die("No successful login to MySQL account."); 
    mysql_select_db("$db_name")or die("cannot select DB");

    // username and password sent from form 
    $myusername=$_POST['myusername'];
    $mypassword=$_POST['mypassword'];

    // ADDED FOR ENCRYPTION
    // encrypt password 
    $encrypted_mypassword=md5($mypassword);

    // To protect MySQL injection (more detail about MySQL injection)
    $myusername stripslashes($myusername);
    $mypassword stripslashes($mypassword);
    $myusername mysql_real_escape_string($myusername);
    $mypassword mysql_real_escape_string($mypassword);

    //$sql="SELECT * FROM $tbl_name WHERE username='$myusername' and password='$mypassword'";
    //$result=mysql_query($sql);

    //ADDED FOR ENCRYPTION - revert to form above if not desired
    $sql="SELECT * FROM $tbl_name WHERE username='$myusername' and password='$encrypted_mypassword'";
    $result=mysql_query($sql);

    // Mysql_num_row is counting table row
    $count=mysql_num_rows($result);
    // If result matched $myusername and $mypassword, table row must be 1 row

    if($count==1){
    // Register $myusername, $mypassword and redirect to file "login_success.php"
    session_register("myusername");
    session_register("encrypted_mypassword"); 
    header("location:login_success.php");
    }
    else {
    echo 
    "Wrong Username or Password";
    }
    ?>
    login_success.php:
    PHP Code:
    <?
    // Check if session is not registered , redirect back to main page. 
    // Put this code in first line of web page. 
    session_start();
    if(!
    session_is_registered(myusername)){
    header("location:index.php");
    }
    ?>

    <html>
    <body>
    Login Successful
    </body>
    </html>

    What I want to do now is figure out the overall structure of a more mature/sophisticated PHP/MySQL login system so that subsequent pages are not viewable unless the user is actually logged in. I found an article here (http://www.devshed.com/c/a/PHP/Creat...-Login-Script/) detailing the code needed for a secure PHP login. The problem is that I don't know what file to put each chunk of code in. I can take a semi-educated guess for some, but for others I have no clue.

    This chunk, for instance, I would guess goes into a PHP file (like my checklogin.php above and NOT in the index page) to check the login credentials:
    PHP Code:
    function &db_connect() {
    require_once 
    'DB.php';
    PEAR::setErrorHandling(PEAR_ERROR_DIE);
    $db_host 'localhost';
    $db_user 'shaggy';
    $db_pass 'password';
    $db_name 'shaggy';
    $dsn "mysql://$db_user:$db_pass@unix+$db_host/$db_name";
    $db DB::connect($dsn);
    $db->setFetchMode(DB_FETCHMODE_OBJECT);
    return 
    $db;

    But am I right about this? I have no clue.

    And this part:
    PHP Code:
    function session_defaults() {
    $_SESSION['logged'] = false;
    $_SESSION['uid'] = 0;
    $_SESSION['username'] = '';
    $_SESSION['cookie'] = 0;
    $_SESSION['remember'] = false;
    }

    if (!isset(
    $_SESSION['uid']) ) {
    session_defaults();

    Would this go in each secure page, or would this just go in the same checklogin.php file as the above?

    These three seem to pretty obviously go into a checklogin.php type of file:
    PHP Code:
    function _checkLogin($username$password$remember) {
    $username $this->db->quote($username);
    $password $this->db->quote(md5($password));
    $sql "SELECT * FROM member WHERE " .
    "username = $username AND " .
    "password = $password";
    $result $this->db->getRow($sql);
    if ( 
    is_object($result) ) {
    $this->_setSession($result$remember);
    return 
    true;
    } else {
    $this->failed true;
    $this->_logout();
    return 
    false;
    }





    function 
    _setSession(&$values$remember$init true) {
    $this->id $values->id;
    $_SESSION['uid'] = $this->id;
    $_SESSION['username'] = htmlspecialchars($values->username);
    $_SESSION['cookie'] = $values->cookie;
    $_SESSION['logged'] = true;
    if (
    $remember) {
    $this->updateCookie($values->cookietrue);
    }
    if (
    $init) {
    $session $this->db->quote(session_id());
    $ip $this->db->quote($_SERVER['REMOTE_ADDR']);

    $sql "UPDATE member SET session = $session, ip = $ip WHERE " .
    "id = $this->id";
    $this->db->query($sql);
    }
    }



    function 
    updateCookie($cookie$save) {
    $_SESSION['cookie'] = $cookie;
    if (
    $save) {
    $cookie serialize(array($_SESSION['username'], $cookie) );
    set_cookie('mtwebLogin'$cookietime() + 31104000'/directory/');
    }

    And these two would pretty obviously go into each secured page:
    PHP Code:
    function _checkRemembered($cookie) {
    list(
    $username$cookie) = @unserialize($cookie);
    if (!
    $username or !$cookie) return;
    $username $this->db->quote($username);
    $cookie $this->db->quote($cookie);
    $sql "SELECT * FROM member WHERE " .
    "(username = $username) AND (cookie = $cookie)";
    $result $this->db->getRow($sql);
    if (
    is_object($result) ) {
    $this->_setSession($resulttrue);
    }
    }


    function 
    _checkSession() {
    $username $this->db->quote($_SESSION['username']);
    $cookie $this->db->quote($_SESSION['cookie']);
    $session $this->db->quote(session_id());
    $ip $this->db->quote($_SERVER['REMOTE_ADDR']);
    $sql "SELECT * FROM member WHERE " .
    "(username = $username) AND (cookie = $cookie) AND " .
    "(session = $session) AND (ip = $ip)";
    $result $this->db->getRow($sql);
    if (
    is_object($result) ) {
    $this->_setSession($resultfalsefalse);
    } else {
    $this->_logout();
    }

    So how much of this do I have wrong so far?


    If this were HTML or CSS I would just look at other people's work and dissect it until I figure out how it works. In this case though, it's not viewable and I have no idea where to begin putting these code snippets.

    If I can get one sample working I can start picking it apart but until then I am out of my element. Can anyone help me sort this out or give me a dummy setup (zip) of a semi-sophisiticated login setup that they use so I can study up on it?

    Also, is the md5 hash really as effective for encrypting passwords as I keep reading it is or should I be looking at different possibilities?

    So many questions for a hungry mind!
    The object of opening the mind, as of opening the mouth, is to shut it again on something solid. –G.K. Chesterton
    See Mediocrity in its Infancy
    It's usually a good idea to start out with this at the VERY TOP of your CSS: * {border:0;margin:0;padding:0;}
    Seek and you shall find... basically:
    validate your markup | view your page cross-browser/cross-platform | free web tutorials | free hosting

  • #2
    Regular Coder sea4me's Avatar
    Join Date
    Jan 2009
    Location
    Damn, I don't know...
    Posts
    390
    Thanks
    11
    Thanked 28 Times in 27 Posts
    Well I recommend you to use:
    http://evolt.org/node/60384

    It explains what each file does and you'll learn from it....

    That was my script that I played with and then more deeply into PHP

  • #3
    Supreme Master coder! abduraooft's Avatar
    Join Date
    Mar 2007
    Location
    N/A
    Posts
    14,866
    Thanks
    160
    Thanked 2,224 Times in 2,211 Posts
    PHP Code:
    // To protect MySQL injection (more detail about MySQL injection)
    $myusername stripslashes($myusername);
    $mypassword stripslashes($mypassword);
    $myusername mysql_real_escape_string($myusername);
    $mypassword mysql_real_escape_string($mypassword); 
    You don't need to strip the slashes, unless magic_quote_gpc is enabled, I'd recommend you to read http://www.codingforums.com/showthread.php?t=144149

    PHP Code:
    session_register("myusername");
    session_register("encrypted_mypassword"); 
    session_register() is deprecated, always check the manual for latest updates.
    The Dream is not what you see in sleep; Dream is the thing which doesn't let you sleep. --(Dr. APJ. Abdul Kalam)

  • #4
    Senior Coder Rowsdower!'s Avatar
    Join Date
    Oct 2008
    Location
    Some say it's everything.
    Posts
    2,027
    Thanks
    5
    Thanked 397 Times in 390 Posts
    Quote Originally Posted by sea4me View Post
    Well I recommend you to use:
    http://evolt.org/node/60384

    It explains what each file does and you'll learn from it....

    That was my script that I played with and then more deeply into PHP
    Ooh, this looks promising. Thanks!

    @ abduraooft, I guess I got a bad tutorial before. Anyway, my first emphasis is on understanding the nuts and bolts before I work on the polishing of the code. It's probably not the most efficient way, but it's just how I like to learn. Manual reading will come further on down the road. I appreciate the input, though. I'll be checking up on the strip slash/magic quotes issue to make sure I don't get funky data in the database.
    The object of opening the mind, as of opening the mouth, is to shut it again on something solid. –G.K. Chesterton
    See Mediocrity in its Infancy
    It's usually a good idea to start out with this at the VERY TOP of your CSS: * {border:0;margin:0;padding:0;}
    Seek and you shall find... basically:
    validate your markup | view your page cross-browser/cross-platform | free web tutorials | free hosting

  • #5
    Senior Coder
    Join Date
    Apr 2007
    Location
    Quakertown PA USA
    Posts
    1,028
    Thanks
    1
    Thanked 125 Times in 123 Posts
    For Persistent Logins (aka 'Remember Me'), here is a very good article: http://jaspan.com/improved_persisten..._best_practice
    John

  • #6
    Senior Coder Rowsdower!'s Avatar
    Join Date
    Oct 2008
    Location
    Some say it's everything.
    Posts
    2,027
    Thanks
    5
    Thanked 397 Times in 390 Posts
    I read something similar that suggested adding an IP address field check (IP address updated on the DB with each login, I suppose) to the session validation as well for even better security for the user's login. Is there any merit to this or would the dynamic IP addresses of users (where applicable) be an issue?
    The object of opening the mind, as of opening the mouth, is to shut it again on something solid. –G.K. Chesterton
    See Mediocrity in its Infancy
    It's usually a good idea to start out with this at the VERY TOP of your CSS: * {border:0;margin:0;padding:0;}
    Seek and you shall find... basically:
    validate your markup | view your page cross-browser/cross-platform | free web tutorials | free hosting


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •