Welcome to Virtual Pet List!

Wanting to join the rest of our members? Feel free to sign up today. Like what you see? Then join our community! You'll love it! Its free!

Sign Up
  1. virtual pet mascot

    Virtual Pets

    Welcome to the Virtual Pet list forum!
    We're a virtual pets and sim games community and we're the largest forum in our industry. We have a lot of virtual pet sites' owners and sim game owners that are quite active on our online community. Along with artists, writers and programmers that come here looking for work and games to work for. Our members who are artists sell art in our art marketplace and programmers are allowed to sell their scripts in the programming marketplace. We've been opened since 2011, however, we've owned our domain name since 2004 and since then we've grown and expanded quite nicely. What are you waiting for, why don't you join today?

    Our list of virtual pet sites and directory of sim games have a lot of games listed that you can try out and possibly enjoy. If you're still curious about a game to play, you can check out some of our game reviews that were written by some of our great contributors and our interviews with respective virtual pet site owners, sim game owners, artists, writers and programmers that have done work in this industry as a whole.

Starting a petsite: Log in and Logout

Discussion in 'Guides' started by spektyr, Dec 24, 2011.

  1. spektyr
    Offline

    spektyr New Member VPL Member

    Joined:
    Mar 14, 2011
    Messages:
    51
    Likes Received:
    7
    Trophy Points:
    0
    This tutorial assumes you've completed the previous registration tutorial: http://www.virtualpetlist.com/showthread.php/6261-Starting-a-petsite-a-basic-registration-page
    The code does not have to be exactly the same, but I'll be making assumptions about the way your 'users' tables is designed and what the columns are called.

    The first thing you'll need is a login.php. In this file we'll show the user the login form, then process the information the user submits. If the information is valid they will be logged in, shown a message, then redirected to the home page. If the data is invalid, they will be presented with an error message and the login form. This time we'll start with the login form in a separate function, like we did at the end of the registration form.
    PHP:
    <?php
    require_once('inc/header.inc.php');

    function 
    display_login($user_name "") {
        
    ?>
        <form action="login.php" method="post">
        Username: <input type="text" name="user_name" /><br />
        Password: <input type="password" name="user_pass" /><br />
        <input type="submit" name="login" value="Login!" /><br />
        </form>
        <?php
    }

    require_once(
    'inc/footer.inc.php');
    ?>
    Now we'll call it from the appropriate if/else section.
    PHP:
    if(isset($_POST['login'])) {
        if(isset(
    $error_messages)) {
            echo 
    $error_messages;
        }
        echo 
    "Here are some variables: ";
        
    var_dump($_POST);
    } else {
        
    display_login();
    }
    Notice how similar this is looking to our registration form? Go ahead and test submitting the form and make sure you can see all the variables.

    Now we need to do something to the username that we needed to do in the registration form: make sure it fits our username convention of letters, numbers, and underscores.
    PHP:
    $user_name $_POST['user_name'];

    if (
    preg_match('/[^A-Za-z0-9_]/'$user_name)) {
        
    $error_messages .= "Usernames can only contain letters, numbers, and the underscore character.<br />";
    }
    We don't have to do any validation of the password - all we have to do is hash it, using the salt (we chose the username), then select from the 'users' table where the row contains the sanitized username and the hashed password. Here we hash the password again:
    PHP:
    $user_pass $_POST['user_pass'];
    $pass_1 hash("sha256"$user_pass $user_name);
    Here's the SELECT statement:
    PHP:
    $query $my_mysqli->query("SELECT * FROM `users` WHERE `username` = '$user_name' AND `password` = '$user_pass'");
    Finally, if we found the user in the table we need to log them in. Logging in means giving the user a cookie. A cookie is a small amount of information that corresponds to a domain. Every time you go to 'virtualpetlist.com', your computer sends the cookie VPL gave you with your page request. If you are logged out (don't have a cookie set), no cookie is sent. Depending on what you're trying to do, VPL may ask you to log in again.

    Cookies are set using the setcookie() function and we'll be using the following options:
    name: The name by which you want to identify the cookie.
    value: The the value of the cookie. In this example we're going to give the cookie the value of the username and password, separated by a colon.
    expire: The time until the cookie expires in seconds. NULL or empty for no expiration date. We'll set the cookie to expire after one week.
    path: We'll set it to "/", or the root of the current domain.
    domain: The domain the cookie is valid for - "" for the current domain.
    You can read about more options by going here: http://php.net/manual/en/function.setcookie.php
    PHP:
    if($query->num_rows) {
        
    $one_week time() + (60*60*24*7);
        
    setcookie('cookiename'"$user_name:$pass_1"$one_week"/""");
    }
    Here's what your code should look like now: http://www.leslieapland.org/tutorial/2/step1/login.php

    Now the cookie is set we'll redirect the user to the main page.
    PHP:
    if($query->num_rows) {
        
    …
        header
    ("Location: index.php");
    }
    Upon logging in, you may notice that you are directed to a page that doesn't exist. Go ahead and create a page called index.php. Next we want to greet the newly logged in user by saying their username (Welcome, username!) on the front page. So how do we know that a user is logged in? We need to check whether a cookie is set, and if it is check the database to verify the user's information. Fortunately PHP provides us with an easy interface for cookies: The variable $_COOKIE.
    PHP:
    // Variables for later
    $username "";
    $userid 0;

    // Check if cookie is set
    if(isset($_COOKIE['mysite'])) {
        
    $creds explode(':'$_COOKIE['mysite']);
        
    $query $my_mysqli->query("SELECT * FROM `users` WHERE `username` = '$creds[0]' AND `password` = '$creds[1]");
        
        if(!
    $query->num_rows) {
            
    // Cookie is set, but it is incorrect. Unset the cookie; move on
            
    setcookie("mysite"""time() - 3600"/" "mysite.com");
        } else {
            
    // Cookie is correct. Put values in the variables
            
    $query $query->fetch_object();
            
    $username $query->username;
            
    $userid $query->id;
        }
    }
    This is a great bit of code - so useful, in fact, that it can be used everywhere! While we CAN put it in the index to check if a user is logged in, this piece should actually be on every page. So go ahead and put this in the header, right after the including of access.inc.php. Now the username and userid variables can be used wherever the header file is included, which is everywhere.

    Let's test this by going to the index and displaying different welcomes depending on whether the user is logged in or not. We can see that the $username variable is set to "" if the user is not logged in, so let's check for that.
    PHP:
    require_once("inc/header.inc.php");

    if(empty(
    $username)) {
        echo 
    "Welcome, guest!";
    } else {
        echo 
    "Welcome, $username!";
    }

    require_once(
    "inc/footer.inc.php");
    Here's what your code should look like now: http://www.leslieapland.org/tutorial/2/step2/

    Go ahead and make sure that you can log in and see the personalized welcome message. To test the welcome message when you are logged out, delete your cookies.

    The final step in this tutorial is the logout. This is a very simple script because unsetting cookies is so simple. Modern web browsers delete cookies when the "expire" value is in the past. So that's pretty much all the logout page has to do - use setcookie() to modify the cookie like we did in the header when the credentials were incorrect, then we'll throw in a nice redirect back to the main page. Create a logout.php and add the following:

    PHP:
    <?php
    require_once("inc/header.inc.php");

    setcookie("mysite"""time()-3600"/""mysite.com");

    header("Location: index.php");
    Go ahead and test that you are logging out correctly.
    Here is all the code: http://www.leslieapland.org/tutorial/2/step3/

    Look out for my next tutorial, in which I will cover creating user profiles!
    FlyingApe likes this.
  2. Ajax
    Offline

    Ajax Mod & Artist | Need Help? Moderator Approved Artist

    Joined:
    Jan 22, 2011
    Messages:
    4,662
    Likes Received:
    177
    Trophy Points:
    73
    Oooo, quite nice. This will really help some people out :D.

    Edit;;;;; Oh I needs to show this to my friend.
  3. Keith
    Offline

    Keith Member VPL Member

    Joined:
    Feb 1, 2011
    Messages:
    513
    Likes Received:
    82
    Trophy Points:
    28
    I don't suggest the whole inc/header.inc.php /inc/footer.inc.php on every page, but otherwise this is a solid tutorial.
  4. Don Relentless
    Offline

    Don Relentless Member VPL Member

    Joined:
    Oct 26, 2011
    Messages:
    217
    Likes Received:
    18
    Trophy Points:
    18
    Location:
    England
    WOOT! Yet another great tutorial!
  5. myrianna
    Offline

    myrianna Approved Artist Approved Artist Pet Game Owner VPL Member

    Joined:
    Apr 24, 2011
    Messages:
    456
    Likes Received:
    35
    Trophy Points:
    38
    if someone grabs that cookie, isn't it going to log them in as that user?
  6. spektyr
    Offline

    spektyr New Member VPL Member

    Joined:
    Mar 14, 2011
    Messages:
    51
    Likes Received:
    7
    Trophy Points:
    0
    Are you asking about what will happen if an attacker intercepts the cookie using something like Wireshark? If that happens then yes, they can use one of several cookie editors (I've used one myself to log in as someone else, though for a good cause) to edit a cookie and make them appear as another user. I agree this is a flaw, however, most pet sites do not use SSL and I don't know enough about the process of getting a certificate to write documentation on the process. Certificates are expensive, or at least used to be.
  7. JohnMaguire2013
    Offline

    JohnMaguire2013 New Member VPL Member

    Joined:
    Feb 28, 2012
    Messages:
    30
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Ann Arbor, MI
    I think using sessions would be better than cookies with the username and password hash in cleartext. If a user were somehow able to get that cookie (either with a packet sniffer, through a cookie grabbing method, etc.) they would be able to login as the username any time they like. Sessions expire however, especially if you control sessions in a database. It also means a hash (even if it's salted and hashed well) wouldn't be given to the attacker.
    <br /><br />
    This is also nice because you only have to set $_SESSION['username'] = $user_name; and you don't have to check on every page load if the user is actually logged in by comparing a username and password to the database. Instead you can be pretty positive that the user is who the session says they are, as session variables can only be set server-side, where as cookie variables can be set on the client-side.
    <br /><br />
    Additionally, with the example you provided (that is, running the query without any validation on the cookie,) I could use the cookie to perform a MySQL injection attempt.
    <br /><br />
    Also, your
    PHP:
    setcookie("mysite"""time() - 3600"/" "mysite.com");
    line is missing a comma after "/".
    Last edited: Feb 28, 2012
  8. nobackseat
    Offline

    nobackseat Member VPL Member

    Joined:
    Jan 22, 2011
    Messages:
    505
    Likes Received:
    43
    Trophy Points:
    28
    Location:
    Florida
    SSL is not a fix-all, and is pretty ridiculous for pet sites imo. There's still XSS...

    Attach an IP to the hash, and problem solved. I have yet to encounter problems with this solution.

    NBS
  9. JohnMaguire2013
    Offline

    JohnMaguire2013 New Member VPL Member

    Joined:
    Feb 28, 2012
    Messages:
    30
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Ann Arbor, MI
    SSL really isn't a solution to any server-side vulns. However, I still think sessions would be more secure (and as you said, you could add the IP to the session, and check that on page load, making it much more secure.)
  10. nobackseat
    Offline

    nobackseat Member VPL Member

    Joined:
    Jan 22, 2011
    Messages:
    505
    Likes Received:
    43
    Trophy Points:
    28
    Location:
    Florida
    I don't really see how you figure sessions being 'more secure'. Sessions are still essentially cookies, which means they can be grabbed via XSS. You can still be session hijacked. And, they're also stored on the server, which is just another way to access the data, if the server is not setup properly. I believe it comes down to what is stored in the cookies, which is what may make them 'less secure' than sessions, however fundamentally they're aren't any less secure than sessions, to my understanding.

    NBS
  11. JohnMaguire2013
    Offline

    JohnMaguire2013 New Member VPL Member

    Joined:
    Feb 28, 2012
    Messages:
    30
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Ann Arbor, MI
    The way I see it, cookies provide one more entry point for users to insert arbitrary code (i.e. the MySQLi which is possible in this login / logout system.) Additionally, it provides more information to an attacker (a username and a hash, as opposed to an identifier as to where that information is stores on the server.) You are correct that if they had the right access to the server they could gain that information, but I believe that you usually need to work a good bit harder for that. (Unless a simple LFI would allow access to the sessions file? What's the default permissions on it?)
  12. nobackseat
    Offline

    nobackseat Member VPL Member

    Joined:
    Jan 22, 2011
    Messages:
    505
    Likes Received:
    43
    Trophy Points:
    28
    Location:
    Florida
    LFI would do it, but even just a directory traversal attack is what is needed.

    Good point about arbitrary code, however it is possible (and I'm sure there are people using it this way), to insert the session's ID directly into the database, and just have a table full of logged in user IDs and their session equivalent. Arbitrary code is possible then too.

    You assume that cookie means username and a hash, when there are infinite combinations of using cookies for login systems. It seems a lot of people do their own unique way too. It could be a custom algorithm, which can decode the data stored, or the username could be placed in the middle of a hash, after a certain amount of characters, etc. And even then, there are people, who don't store any form of the password in the cookie. Rather, a hash of the IP, and email address or something. But yes, I admit that cookies allow more room for error.

    EDIT: Every file at least has the read permission, no? That's all that's needed. The server itself has to read from the file, right?

    NBS
  13. Hituro
    Offline

    Hituro Supporter Pet Game Owner VPL Supporter VPL Member

    Joined:
    Feb 1, 2011
    Messages:
    1,399
    Likes Received:
    88
    Trophy Points:
    48
    If I issue a cookie which is a hash of some unique information (salt+ip+password or whatever) then I have to confirm that cookie on each page, by recalculating the hash and checking it matches the one that's been sent, to make sure the cookie has not be intercepted / spoofed.

    If on the other hand I use a session, then I still need to do something to check you've not hijacked the session, which probably means looking it up in a table of sessionid -> user, and then doing the same sort of checks. If I don't expect cookie interception (e.g. an intranet web app) then I can just trust the session cookie, but otherwise I have to assume it might have been hijacked and check things like whether your IP is the same one I issued the session too (etc.) But of course those things are ALSO spoofable .....
  14. JohnMaguire2013
    Offline

    JohnMaguire2013 New Member VPL Member

    Joined:
    Feb 28, 2012
    Messages:
    30
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Ann Arbor, MI
    You wouldn't even have to look the session up in a table. Check $_SESSION['ip'] == $_SERVER['REMOTE_ADDR'].
  15. Hituro
    Offline

    Hituro Supporter Pet Game Owner VPL Supporter VPL Member

    Joined:
    Feb 1, 2011
    Messages:
    1,399
    Likes Received:
    88
    Trophy Points:
    48
    Which is another way of saying I still need to confirm something about the session before I trust it.
  16. JohnMaguire2013
    Offline

    JohnMaguire2013 New Member VPL Member

    Joined:
    Feb 28, 2012
    Messages:
    30
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Ann Arbor, MI
    Yes, I'm not denying that. But you're also giving the end-user less information with sessions, and less of an opening for attack.
  17. Keith
    Offline

    Keith Member VPL Member

    Joined:
    Feb 1, 2011
    Messages:
    513
    Likes Received:
    82
    Trophy Points:
    28
    The best way of doing this is inserting a row into the user table with a hashed string that changes on every page load (and in the cookie). If it's stolen, it doesn't matter.
  18. spektyr
    Offline

    spektyr New Member VPL Member

    Joined:
    Mar 14, 2011
    Messages:
    51
    Likes Received:
    7
    Trophy Points:
    0
    Thank you, this is an excellent solution!
  19. myrianna
    Offline

    myrianna Approved Artist Approved Artist Pet Game Owner VPL Member

    Joined:
    Apr 24, 2011
    Messages:
    456
    Likes Received:
    35
    Trophy Points:
    38
  20. JohnMaguire2013
    Offline

    JohnMaguire2013 New Member VPL Member

    Joined:
    Feb 28, 2012
    Messages:
    30
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Ann Arbor, MI
    It's no better than tying an IP to the session -- in fact, possibly worse. With an IP tied to the session, there is no way they would be able to use the cookie (containing the session ID.) With the token generated on page load, they likely would not be able to use it, but what if they happened to grab the cookie just as the user was finishing up?
Similar Threads
Forum Title Date
Guides Starting a petsite - a basic registration page Sep 11, 2011
Guides Starting a pet site - User Profiles May 28, 2012
Guides Guide to starting out on Evodragon! Jan 24, 2012
Guides Petsite: The Planning Aug 8, 2011

Share This Page