Jump to content

PHP Login System Help


MightyBeforeGod

Recommended Posts

Hi All!

 

This is my first post here, so if there are some things I miss or something more I need to do please let me know.

 

I tried searching the forum for the answer first but could not find anything.

 

So here is the thing; I followed a tutorial I found about building a login system for my website. The tutorial worked perfectly, except I needed it to redirect to a user specific page instead of a static page on login. I made the necessary changes to the script, and now it redirects to the user specific page, but does not recognize that I am logged in so it will not show me the content.

 

In the interest of full disclosure, I am not very good at PHP and lack a fundamental understanding of it. I am enrolled in some Udemy courses to try to rectify that, but I needed the login system ASAP, so copy and paste programming was my only option. I know, I know. I am a terrible human being and should be thrown into the sun. I agree. I am in counseling to try to deal with it.

 

The tutorial I used can be found here: http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL.

 

Here is the relevant code:

 

process_login.php:

 

<?php


include_once 'db_connect.php';
include_once 'functions.php';


sec_session_start(); // Our custom secure way of starting a PHP session.


if (isset($_POST['email'], $_POST['p'])) {
    $email = $_POST['email'];
    $password = $_POST['p']; // The hashed password.


$page = login($email, $password, $mysqli);
if ($page == true) {
  // Login success        
  header('Location: '. $page);
   exit();


    } else {
        // Login failed 
        header('Location: ../error.php?error=1');
    }
} else {
    // The correct POST variables were not sent to this page. 
    echo 'Invalid Request';
}
 
 
functions.php: 
 
<?php
include_once 'psl-config.php';


function sec_session_start() {
    $session_name = 'sec_session_id';   // Set a custom session name
    $secure = SECURE;
    // This stops JavaScript being able to access the session id.
    $httponly = true;
    // Forces sessions to only use cookies.
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
        exit();
    }
    // Gets current cookies params.
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params($cookieParams["lifetime"],
        $cookieParams["path"], 
        $cookieParams["domain"], 
        $secure,
        $httponly);
    // Sets the session name to the one set above.
    session_name($session_name);
    session_start();            // Start the PHP session 
    session_regenerate_id();    // regenerated the session, delete the old one. 
}


function login($email, $password, $mysqli) {
    // Using prepared statements means that SQL injection is not possible. 
    if ($stmt = $mysqli->prepare("SELECT id, username, password, salt, page 
        FROM members
       WHERE email = ?
        LIMIT 1")) {
        $stmt->bind_param('s', $email);  // Bind "$email" to parameter.
        $stmt->execute();    // Execute the prepared query.
        $stmt->store_result();


        // get variables from result.
        $stmt->bind_result($user_id, $username, $db_password, $salt, $page);
        $stmt->fetch();


        // hash the password with the unique salt.
        $password = hash('sha512', $password . $salt);
        if ($stmt->num_rows == 1) {
            // If the user exists we check if the account is locked
            // from too many login attempts 


            if (checkbrute($user_id, $mysqli) == true) {
                // Account is locked 
                // Send an email to user saying their account is locked
                return false;
            } else {
                // Check if the password in the database matches
                // the password the user submitted.
                if ($db_password == $password) {
                    // Password is correct!
                    // Get the user-agent string of the user.
                    $user_browser = $_SERVER['HTTP_USER_AGENT'];
                    // XSS protection as we might print this value
                    $user_id = preg_replace("/[^0-9]+/", "", $user_id);
                    $_SESSION['user_id'] = $user_id;
                    // XSS protection as we might print this value
                    $username = preg_replace("/[^a-zA-Z0-9_\-]+/", 
                                                                "", 
                                                                $username);
                    $_SESSION['username'] = $username;
                    $_SESSION['login_string'] = hash('sha512', 
                              $password . $user_browser);
                    // Login successful.
                    return $page;
                } else {
                    // Password is not correct
                    // We record this attempt in the database
                    $now = time();
                    $mysqli->query("INSERT INTO login_attempts(user_id, time)
                                    VALUES ('$user_id', '$now')");
                    return false;
                }
            }
        } else {
            // No user exists.
            return false;
        }
    }
}


function checkbrute($user_id, $mysqli) {
    // Get timestamp of current time 
    $now = time();


    // All login attempts are counted from the past 2 hours. 
    $valid_attempts = $now - (2 * 60 * 60);


    if ($stmt = $mysqli->prepare("SELECT time 
                             FROM login_attempts 
                             WHERE user_id = ? 
                            AND time > '$valid_attempts'")) {
        $stmt->bind_param('i', $user_id);


        // Execute the prepared query. 
        $stmt->execute();
        $stmt->store_result();


        // If there have been more than 5 failed logins 
        if ($stmt->num_rows > 5) {
            return true;
        } else {
            return false;
        }
    }
}


function login_check($mysqli) {
    // Check if all session variables are set 
    if (isset($_SESSION['user_id'], 
                        $_SESSION['username'], 
                        $_SESSION['login_string'])) {


        $user_id = $_SESSION['user_id'];
        $login_string = $_SESSION['login_string'];
        $username = $_SESSION['username'];


        // Get the user-agent string of the user.
        $user_browser = $_SERVER['HTTP_USER_AGENT'];


        if ($stmt = $mysqli->prepare("SELECT password 
                                      FROM members 
                                      WHERE id = ? LIMIT 1")) {
            // Bind "$user_id" to parameter. 
            $stmt->bind_param('i', $user_id);
            $stmt->execute();   // Execute the prepared query.
            $stmt->store_result();


            if ($stmt->num_rows == 1) {
                // If the user exists get variables from result.
                $stmt->bind_result($password);
                $stmt->fetch();
                $login_check = hash('sha512', $password . $user_browser);


                if ($login_check == $login_string) {
                    // Logged In!!!! 
                    return true;
                } else {
                    // Not logged in 
                    return false;
                }
            } else {
                // Not logged in 
                return false;
            }
        } else {
            // Not logged in 
            return false;
        }
    } else {
        // Not logged in 
        return false;
    }
}


function esc_url($url) {


    if ('' == $url) {
        return $url;
    }


    $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);


    $strip = array('%0d', '%0a', '%0D', '%0A');
    $url = (string) $url;


    $count = 1;
    while ($count) {
        $url = str_replace($strip, '', $url, $count);
    }


    $url = str_replace(';//', '://', $url);


    $url = htmlentities($url);


    $url = str_replace('&', '&', $url);
    $url = str_replace("'", ''', $url);


    if ($url[0] !== '/') {
        // We're only interested in relative links from $_SERVER['PHP_SELF']
        return '';
    } else {
        return $url;
    }
}
Edited by mac_gyver
code tags around posted code please
Link to comment
Share on other sites

To add to CroNiX's respons: I did not read the entire thing, but I do see that the script sets the following session value when authentication passes

 

 $_SESSION['user_id'] = $user_id;

 

So, in addition to starting the session on any pages that require the user to be authenticated, you would check to see if that session key isset() to determine if they are logged in. Plus, if you want to limit access to that page for only that user, you would want to check the value of the session key to see if it is the same one as the page being requested.

Link to comment
Share on other sites

See step 8 of 8 to see how to protect your pages using the code form that tutorial.

 

Also the following lines in process_login.php (specifically the header() line) is not quite right.

$page = login($email, $password, $mysqli);
if ($page == true) {
  // Login success        
  header('Location: '. $page);

In the header you are redirecting to $page. But hang on $page contains a boolean value (true or false) as that is what the login() function returns, true if the user successfully authenticates and false if they don't.

 

You need to specify the actual url for where you want to redirect the user to, example for redirecting to profile.php page

header('location: profile.php');
Link to comment
Share on other sites

@Ch0cu3r

 

The function login() in that code returns FALSE on errors. But, on success it returns $page which is defined from a return value from the DB.

 

@MightBeforeGod,

 

You do not need to include the page URL for the users in the database. You should just have a generic page (e.g. showUserPage.php). Then you can simply define the page adding the user's ID as a parameter to the URL: showUserPage.php?id=$userID

Link to comment
Share on other sites

 

 

@Ch0cu3r

 

The function login() in that code returns FALSE on errors. But, on success it returns $page which is defined from a return value from the DB.

Oh.... MightBeforeGod has modified the original code for the login() function.  I was looking at the code from the tutorial.  :facepalm:

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.