GumbiRo Posted December 9, 2013 Share Posted December 9, 2013 (edited) 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 December 9, 2013 by GumbiRo Quote Link to comment Share on other sites More sharing options...
MDCode Posted December 9, 2013 Share Posted December 9, 2013 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. Quote Link to comment Share on other sites More sharing options...
GumbiRo Posted December 9, 2013 Author Share Posted December 9, 2013 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 Quote Link to comment Share on other sites More sharing options...
GumbiRo Posted December 9, 2013 Author Share Posted December 9, 2013 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. Quote Link to comment Share on other sites More sharing options...
DavidAM Posted December 10, 2013 Share Posted December 10, 2013 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. Quote Link to comment Share on other sites More sharing options...
GumbiRo Posted December 10, 2013 Author Share Posted December 10, 2013 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! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.