Jump to content

Multiple session_start, regenerate_session. Trying to do a Secure Login.


GumbiRo

Recommended Posts

Hello everyone! Im learning how to create a "secure" way to login...
But for the moment Im stuck with a couple of things.

Here's the files. I'll be explaining what's wrong in each part...

Here's my login.php

 

Casual form that asks a user to login.

 

*According to the lesson,  the <?php is after the body, but for best practice I've seen that people put every session starting before the head. The lesson didn't explain why it should be where it is now. (after body) If you guys could tell me I'd be grateful! 

 

<html>
<head><title>Log In</title>
<script type="text/javascript" src="sha526.js"></script>
<script type="text/javascript" src="forms.js"></script>
</head>
<body>

<?php
if(isset($_GET['error'])) {

echo 'Error logging in.';

} else {

//Include database connection and functions here
	
	include 'functions.php';
	include 'db_connect.php';

sec_session_start();

if(login_check($mysqli) == true) {
	//Add your protected content here.
	} else {
		echo "You're not authorized, <br/> Please login.";
		}
} 

?>
 
<form action = "process_login.php" method="post" name="login_form">

Email: <input type="text" name="email" /> <br />
Password: <input type="password" name="password" id="password" /> <br />
<input type="submit" value="Login" onclick="formhash(this.form,this.form.password);" />

</form>

</body>
</html>

When I try to login. I get sent an unknown error, there's nothing displayed on my browser but the error the hosting site sends when you're seeing a file it doesn't exist.

Here's process_login.php

<?php

	include 'db_connect.php';
	include 'functions.php';
	
	sec_session_start(); // Custom way of starting session
	
if(isset($_POST['email'], $_POST['p'])) {

	$email = $_POST['email'];
	$password = $_POST['p']; //Hashed password
	
	if(login($email, $password, $mysqli) == true) {
	
	//Login Success
	
	echo 'Success, You have Logged In.';
	} else {
	
		//Login Failed
		header('Locaction ./login.php?error=1');
		
		}
	
} else {

	//The correct POST variables were  not sent to this page
	
	echo 'Invalid Request';
	}
	
	
	
include 'functions.php';

sec_session_start();


//Unset all session values
$_SESSION = array();
//Get session parameters
$params = session_get_cookie_params();
// Delete actual cookie
setcookie(session_name(), '', time() - 42000 , $params["path"], $params["domain"], $params["secure"], $params["httpOnly"]);
//Destroy Session
session_destroy();
header('Location: ./');




//Hashed pass from the form

$password = $_POST['p'];
//Create a random salt
$random_salt = hash('sha526', uniqid(mt_rand(1, mt_getrandmax()), true));
//Created salted password (Careful not to overseason)
$password = hash('sha512', $password.$random_salt);

//Add insert  to database script here.
//Make sure you use prepared statements

if($insert_stmt = $mysqli->prepare("INSERT INTO users (username, email, password, salt) VALUES (?, ?, ?, ?)" )) {

	$insert_stmt->bind_param('ssss', $username, $email, $password, $random_salt);
	//Executed  the prepared query
	$insert_stmt->execute();
	
	}
	



?>	

Another error that I have is that It's telling me Im initiating session with the browser constantly, and that I should only do it once. but here's the file 'functions.php' which starts_session besides login.php...

How could I fix this?

<?php
function sec_session_start()
{
	$session_name = 'sec_session_id'; //Set custom session name 
	$secure = false; //Set to true if using https
	$httpOnly = true; //This stops javascript frm accesing the session_id
	
	ini_set('session.use_only_cookies', 1); //Forces Session to use cookies.
	
	$cookieParams = session_get_cookie_params(); //Get cookie parameters
	
	
	
	session_set_cookie_params($cookieParams["lifetime"], $cookieParams["Path"], $cookieParams["domain"], $secure, $httpOnly);
	
		
	session_name($session_name);
	session_start(); //Start php session
	session_regenerate_id(); // regenerate the session, delete the old one.
	
}


function login($email, $password,$mysqli) //Using prepared statements means the SQL injection is not possible.
{
	if($stmt = $mysqli->prepare("SELECT id, username, password, salt FROM users WHERE email = ? LIMIT 1")) {
		
		$stmt->bind_param('s', $email); //Bind email  to parameter
		$stmt->execute(); //Execute QUERY
		$stmt->store_result();
		$stmt->bind_result($user_id, $username, $db_password, $salt); //Get variables from result
		$stmt->fetch();
		$password = hash('sha512', password.$salt); //Hash the password with the unique salt
		
	}
	
	
	if($stmt->num_rows == 1) { //IF user  exist
		//Check if account is locked from too many attempts.
		if(checkbrute($user_id, $msqli) == true) {
			//Account is locked.
			echo 'Account is Locked.';
			//To-Do: Add function to send mail to unlock account.
			return false;
		} else {
		if($db_password == $password) { //Check if the password the user entered is the same as the password in the database.
			//Password is correct!
			
			}
		}
	}
}

function checkbrute($user_id, $msqli)
{
	//Get timestamp f current time.
	$now = time;
	//All login attempts are counted from the last 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 the statement has more than 5 failed logins
	if($stmt->num_rows > 5){
		return true;
		} else {
		return false;
		}
	}
}


function login_check($mysqli) {
	//Check if all 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'];
		
		$user_browser = $_SERVER['HTTP_USER_AGENT']; // Get user-agent string of user
		
		if($stmt = $mysqli->prepare("SELECT password FROM users WHERE id = ? LIMIT 1")) {
		$stmt->bind_param('i',$user_id); //Bind user id to parameter.
		$stmt->execute(); //Execute query
		$stmt->store_result();
		
			if($stmt->num_rows == 1) { //IF user exists
			$stmt->bind_result($password); //Get variables from result
			$stmt->fetch();
			$login_check = hash('sha512', $password.$user_browser);
			if($login_check == $login_string) {
			
				//Logged In
				return true;
				}
			}		
		}
	}
}

?>

And here's db_connect.php just in case you need it, but I don't think you do.

<?php
$servername="localhost";
    $username="userName";
    $db_pass = "QkJ93OpLLlkmNoYgD";
    $db_name = 'db_users_login';
    
    $mysqli = new mysqli($servername,$username,$db_pass,$db_name);
     
 ?>

Thank you for your time and if you have any suggestions Im all ears!

Edited by GumbiRo
Link to comment
Share on other sites

You can't use session_start(); or header(); after any output is sent to the browser. This is why it may be considered best practice for stuff involving headers or processing.

 

process_login.php is starting multiple sessions which is why you get that error.

Link to comment
Share on other sites

You can't use session_start(); or header(); after any output is sent to the browser. This is why it may be considered best practice for stuff involving headers or processing.

 

process_login.php is starting multiple sessions which is why you get that error.

And what do you recommend me doing? as Of what you see on the files, what would you do to solve this?

 

1.Should the login.php have the php code where it is, or should I move it top.

2. Should I remove session_start from the process_login.php?

 

Thanks for your time SocialCloud

Link to comment
Share on other sites

Ok I believe my problem here is this, (...I obviously don't know how to fix this):

 

 

 

 Cannot send session cache limiter - headers already sent (output started at /home1/login/db_connect.php:14)  in/home1/login/functions.php on line 13

 

I've got 2 things:

 

 

 

db_connect && process_login.

 

 

As Im creating a session on functions.php

 

This part of functions.php mainly:

function sec_session_start() {
        $session_name = 'sec_session_id'; // Set a custom session name
        $secure = false; // Set to true if using https.
        $httponly = true; // This stops javascript being able to access the session id. 
 
        ini_set('session.use_only_cookies', 1); // Forces sessions to only use cookies. 
        $cookieParams = session_get_cookie_params(); // Gets current cookies params.
        session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); 
        session_name($session_name); // Sets the session name to the one set above.
        session_start(); // Start the php session
        session_regenerate_id(true); // regenerated the session, delete the old one.     
}

I get errors on session_start and session_regenerate

 

And I also get this error:

 

Warning: Cannot modify header information - headers already sent by (output started at /home1/login/db_connect.php:14) in/home1/login/process_login.php on line 17

<?php

include 'db_connect.php';
include '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.
   if(login($email, $password, $mysqli) == true) {
      // Login success
     header("Location: '..\..\..\logged_success.php");
   } else {
      // Login failed
     header("Location: '..\..\..\?error=1");

   }
} else { 
   // The correct POST variables were not sent to this page.
   echo 'Invalid Request';
}

;?>

Which is the header("Location: '..\.....")

 

Im going mad! I don't know what to do. :(


Thank you guys for your time.

Link to comment
Share on other sites

 Cannot send session cache limiter - headers already sent (output started at /home1/login/db_connect.php:14 in/home1/login/functions.php on line 13

 

 

Warning: Cannot modify header information - headers already sent by (output started at /home1/login/db_connect.php:14) in/home1/login/process_login.php on line 17

session_start() sends a header.

You can NOT send any header() after sending output to the browser.

The error message says the output started at line 14 of db_connect.php.

The db_connect.php code you posted only has 8 or 9 lines, so there must be something after the closing PHP tag ("?>"). Anything after that tag will be sent as output to the browser. If you have blank lines there, you need to remove them. If fact, I don't event put the closing PHP tag in my include files (unless there actually IS HTML to be sent to the browser). PHP is smart enough to know that the end of the file is the end of the PHP in the file.

Link to comment
Share on other sites

session_start() sends a header.

You can NOT send any header() after sending output to the browser.

The error message says the output started at line 14 of db_connect.php.

The db_connect.php code you posted only has 8 or 9 lines, so there must be something after the closing PHP tag ("?>"). Anything after that tag will be sent as output to the browser. If you have blank lines there, you need to remove them. If fact, I don't event put the closing PHP tag in my include files (unless there actually IS HTML to be sent to the browser). PHP is smart enough to know that the end of the file is the end of the PHP in the file.

Thank you very much david. This was the issue,  Im now working on seeing if the script is correct, because for some reason the match isn't happening, but I guess Its up to me to check that out! Have a good one and thank you for your time!

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.