PHP Session destroy twice? - php

Upon entering the "secure" page, I have an if statement asking if the user is logged in, as shown below.
This statement baffles me as the outcome of both statements are the same, but it is the only way for me to end session when refreshing page. So if I change the statement to if (!session == user) {session_destroy} else { continue with session}, refreshing the page will have the session going.
edit The if/else statement in session.php is the one I do not understand. How can I have an if/else statement with two equal outcomes and yet receive two different outcomes in practice. As I enter my login credentials, I enter the session.php. If I refresh, I end up back at index.php. However, my statement claims that if I have session variables, then destroy session. If I do not have session variables, destroy session. What am I overlooking? edit
Secure page session.php below.
<?php
// To connection
require("includes/functions.php");
// Is the user logged in?
if(!isset($_SESSION['user'])) {
//If user not set, destroy session.
session_destroy();
header("Location: index.php");
exit();
} else {
//Here is the funky part, why have if condition with two predicted equal statements, but have two different outcomes.
// If set, destroy session.
session_destroy();
} //Then the anything below should be secure.
?>
My functions.php (the included one) file is actually a connect to db with a session_start(). The login_process.php page looks as follows.
<?php
// Connection
require_once("functions.php");
//Once form has been clicked, the submitted name reappears, but first empty.
$submitted_username = '';
// IS form submitted?
if(!empty($_POST['login']))
{
// Find username
$query = "
SELECT
id,
username,
password,
salt,
email
FROM users
WHERE
username = :username
";
// The parameter values
$query_params = array(
':username' => $_POST['username']
);
try
{
// Execute the query against the database
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
// Login bad first
$login_ok = false;
// Find user
$row = $stmt->fetch();
if($row)
{
// Check password
$check_password = hash('sha256', $_POST['password'] . $row['salt']);
for($round = 0; $round < 65536; $round++)
{
$check_password = hash('sha256', $check_password . $row['salt']);
}
if($check_password === $row['password'])
{
// If match, login good.
$login_ok = true;
}
}
// If allgood session start.
if($login_ok)
{
unset($row['salt']);
unset($row['password']);
//Issue here?
$_SESSION['user'] = $row;
// Redirect user to secret page.
header("Location: session.php");
exit;
}
else
{
// Tell the user they failed
$login_failed = "<p class='clear floatleft'>Login Failed.</p>";
$submitted_username = htmlentities($_POST['username'], ENT_QUOTES, 'UTF-8');
}
} ?>
The require_once in login_process.php is due to login_form.php being added as an include on every page. Thus always creating a session_start();. See login_form below.
<?php include('login_process.php'); ?>
<form action="" method="post">
<!-- Sign in form -->
<label>Username</label>
<input type="text" name="username" value="<?php echo $submitted_username; ?>">
<label>Password</label>
<input type="password" name="password" value="">
<input class="inline" type="submit" name="login" value="Login">
<input class="inline" type="submit" name="signup" value="Sign Up">
</form>
<?php if(isset($login_failed)) {
echo $login_failed;
}
?>
The form is picked up from a tutorial, please understand that I am not as of yet capable of producing such a login form rendering. I like to think that I understand the blocks of code by the comments I have created.
But I digest, I do not understand how the if/else statement in session.php can have two equal values and render differently. So any help on this particular subject would be greatly appreciated.
This question may be a duplicate, I have read so many questions regarding sessions that I feel blind to finding any help.
Thanks in advance.

Digress
Your code is doing exactly what it is written to do. Just as you think it is.
When a user inputs their credentials and is successful in login_process.php at -
if($login_ok)
{
unset($row['salt']);
unset($row['password']);
//Issue here?
$_SESSION['user'] = $row;
// Redirect user to secret page.
header("Location: session.php");
exit;
}
else
{
The user is redirected to session.php to have their session destroyed. Why? Because the code says that if the user has nothing in $_SESSION['user']
if(!isset($_SESSION['user'])) {
//If user not set, destroy session.
session_destroy();
header("Location: index.php");
exit();
then destroy the session.
OTHERWISE destroy session.
So no matter what the user session is destroyed. Successful or not.
The reason you don't get redirected until a refresh is because after you log in --successfully-- your session is destroyed. Then on refresh(of the same page) you satisfy the check for
if(!isset($_SESSION['user'])) {
//If user not set, destroy session.
session_destroy();
header("Location: index.php");
exit();
because $_SESSION['user'] no longer exists. Thus it redirects you to the homepage.
TL;DR session_destroy() cleared $_SESSION['user'] and a refresh on the same page causes user to clear first check of if statement.

Related

Session variables not being transported

I'm learnig PHP (as a hobby) and I wanted to build a simple login page to practice.
I have a form:
<form action="phpAction/checklogin.php" method="POST">
<p>Username:</p>
<input type="text" name="username">
<p>Password:</p>
<input type="password" name="password">
<br><br>
<input type="submit" value="Submit">
<br><br>
You don't have an account yet?
</form>
Posting to the php code:
<?php
// Starts a MySQLi connection to the database
include "../includes/mysqliConn.php";
// Starts a session to keep the user logged in
session_start();
// Posts the username and password from the form and stores it into a session variable
if (isset($_POST["username"]) && isset($_POST["password"])) {
$_SESSION["username"] = $_POST["username"];
$_SESSION["password"] = $_POST["password"];
} else {
die("You cannot be here!");
}
// Checks login
$checklogin = 'SELECT * FROM users WHERE username = $_SESSION["username"] AND password = $_SESSION["password"]';
$result = $conn->query($checklogin);
if ($result->num_rows = 0){
echo "<script language='javascript' type='text/javascript'>alert('Login and/or password wrong!');window.location.href='login.php';</script>";
die();
} else {
// Variable to other pages see that the user is logged in
$_SESSION["islogged"] = "true";
// Redirects to the homepage
header("Location: ../index.php");
}
?>
It sets the session variable "islogged" to true so that other pages can diplay user's information.
In the header of the website I have this:
<?php
if ($_SESSION["islogged"] == "true") {
echo "<a href='#'>Panel</a>";
echo "<a href='#'>Logout</a>";
} else {
echo "<a href='login.php'>Login</a>";
echo "<a href='#'> / </a>";
echo "<a href='signup.php'>Sign Up</a>";
}
?>
When the variable "islogged" is set to "true", the page should display the links Panel and Logout, instead of the Login and Signup ones. But I keep getting the login and signup.
It seems like the session variables are not being "transported".
Any kind of help is appreciated.
PS: Sorry for bad English :P
Thanks
As far as I know anything other then numbers must be enclosed in a ' ' . Just try this one
$checklogin = "SELECT * FROM users WHERE username ='".$_SESSION['username']."' AND password ='".$_SESSION['password']."'";
I hope this works.
To use $_SESSION variables, run session_start() first. The example that you have marked as "in the header of the web site," you're not running session_start() first.
http://php.net/manual/en/function.session-start.php
session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.

Not sure if using isset correctly

I am building up a website that must not show login option when the user is already logged in, i.e. session is active. I have tried working with this but its not returning the desired output. Please help. Thanks.
<?php
if(!isset($_SESSION)) {echo "<li><a href='Employee.php'>Login</a></li>";}
?>
edit:
I am adding the part where I check login details from database and start session.
$query = "SELECT Cust_FName from customer where Cust_ID='$name' and Password='$pass'";
$result = mysqli_query($con, $query);
if(mysqli_num_rows($result)!= false)
{
$row = mysqli_fetch_row($result);
echo row[0];
if(mysqli_num_rows($result) > 0)
{
echo "Logged in!";
session_start();
$_SESSION['userName'] = $row[0];
header("Location: index.php");
}
}
If you want to check if the session is started, you can use
if(session_status() != PHP_SESSION_ACTIVE) {
echo "<li><a href='Employee.php'>Login</a></li>";
}
The problem is that the session als also there if the user isn't logged in. You have to check if e.g. $_SESSION['user_id'] is set:
if(!isset($_SESSION['user_id']) {
echo "<li><a href='Employee.php'>Login</a></li>";
}
In my example $_SESSION['user_id'] will be filled when the user login was successful.
Problem
From your comment:
The login button should only show up when the user has not logged in, and once he does, it should disappear.
Solution
// This would be your login.php page
<?php
session_start();
// process your HTML form, like this
if(isset($_POST['login'])){
// Remember: always validate your form inputs
$name = $_POST['name'];
$pass = $_POST['pass'];
$query = "SELECT Cust_FName from customer where Cust_ID='$name' and Password='$pass'";
$result = mysqli_query($con, $query);
if(mysqli_num_rows($result)!= false){
$row = mysqli_fetch_row($result);
//echo row[0];
if(mysqli_num_rows($result) > 0){
//echo "Logged in!";
$_SESSION['userName'] = $row[0];
header("Location: index.php");
exit(); // exit() is necessary, otherwise the script execution is not terminated. Setting header alone is not enough to redirect.
}
}
}
if(isset($_SESSION['userName'])){
// user is already logged in
// redirect the user to a different page
// header("Location: index.php");
// exit();
}else{
// user is not logged in
// display login option
?>
<!--Your HTML form for login-->
<form action="login.php" method="POST">
<input type="text" name="name" value="" /><br />
<input type="text" name="pass" value="" /><br />
<input type="submit" name="login" value="Login" />
</form>
<?php
}
?>
Edited:
Session is a file that resides in our server and in that file we can store any amount of information. We generally deploy a session cookie on the client's browser.
Before we output any HTML or white space, we need to start our session.
When we do like this,
<?php
session_start();
?>
It will say, go to the browser, get the session id and open the appropriate file and if it didn't find any session id, it will start a new session. User can only see session id, nothing else.
Tip: Remember to clean up sessions from time to time.
Put in the login page
<?php
session_start();
// Store Session Data
$_SESSION['login_user']= $username; // Initializing Session
?>
when you have to check use
<?php
session_start();
// Store Session Data
if(isset($_SESSION['login_user'])){
//do things
}
?>
and on logout
<?php
session_destroy();
?>

Single Page Login getting Constant 500 Server Errors

What I'm Trying To Do
I'm creating a single-page members' area with a login form.
When logged in, the only thing the user should see (at this stage) is a button to logout.
What's going wrong
Whenever there is a match in the database (e.g. the username is correct, or both username and password are correct) there is a 500 Server Error.
Refreshing the page, regardless of if the password is a match, the user gets logged in.
When the user clicks the Logout link, there is also a 500 Server Error.
The Code
<?php
session_start();
if(isset($_GET['logout'])&&$_GET['logout']==='true'){
logout();
header('location: ./');
}
if(isset($_POST['submit'])) {
$email = $_POST['email'];
$password = $_POST['password'];
$hostname = 'REDACTED';
$username = 'REDACTED';
$password = 'REDACTED';
$dbname = 'REDACTED';
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
}
catch(PDOException $e){
echo($e->getMessage());
}
$stmt=$dbh->prepare('SELECT `password`, `id` FROM `tap_users` WHERE `email`=?');
$stmt->execute(array($email));
if($stmt->rowCount()==0){
//incorrect username
header('location: ./?error=user');
exit();
}
$userData = $stmt->fetch(PDO::FETCH_ASSOC);
if($password != $userData['password']) {
//incorrect password
header('location: ./?error=pass');
exit();
} else {
validateUser($userData['id']);
header('location: ./');
}
}
?>
<head></head>
<body>
<?php
if(!isLoggedIn()) {
show_login();
exit();
}
?>
Logout
</body>
</html>
<?php
//Show login form
function show_login(){
echo '<form method="post">
<input type="text" name="email" placeholder="Email Address" />
<input type="password" name="password" placeholder="Password" />
<input type="submit" value="Submit" name="submit" />
</form>
</body>
</html>';
}
//Check if a user is logged in
function isLoggedIn(){
if(isset($_SESSION['valid']) && $_SESSION['valid'])
return true;
return false;
}
//validate the user
function validateUser($userid){
//this is a security measure
session_regenerate_id();
$_SESSION['valid'] = 1;
$_SESSION['userid'] = $userid;
}
//logout the user
function logout(){
//destroy all of the session variables
$_SESSION = array();
session_destroy();
}
?>
what you are doing is if user login is correct then you are redirecting to header('location: ./'); Maybe either you dont have index.php or directory index is off in your apache configuration.
do one thing change it to
header('location:index.php');
it will work.
this is not related to php or mysql, it is server configuration error.
I ran your code through: online php code validator There doesn't seem to be any issues with syntax. The issue could be coming from a permission error on the file. Does the file have execution permissions for the user. in your ftp make sure that the permissions are set to 755. This should allow everyone to read and execute the php code. If that is not the issue then contact your host and ask for the errors, they should be able to give you that information. Another option is to create your own error logging in PHP. You can look at this old stack overflow post on this to continue on making all of your errors visible to a seperate file.

Records Login Entries and Session State

How can I record the login entries and session state? I've search for source codes and ideas but I can't understand some of it. I want to ask a simple code through PHP. I have a code that can login user but does not need MySql database, and I want an idea how to RECORD LOGIN ENTRIES AND SESSION STATE connecting my PHP Login code. Or if you have other option code that need MySql database.
Here's the code:
"CONFIG.PHP"
<?php
$user = "admin";
$pass = "password";
?>
"INDEX.PHP"
<?php
include("config.php");
// Check form if is submited
if(isSet($_POST['trimite'])) {
// Check if user is equal with username and password from config.php
if($_POST['user'] != $user || $_POST['pass'] != $pass) {
echo "Sorry, your data is invalid";
} else {
// Open the session for store user logged
session_start();
// Setting the session
$_SESSION['logat'] = "da";
// Redirecting user to admin page if is logged
Header('Location: admin.php');
}
} else {
// Form
echo '<form action="" method="post">
Username: <input type="text" name="user">
Password: <input type="password" name="pass">
<input type="submit" name="trimite">
</form>';
}
?>
"ADMIN.PHP"
<?php
include("config.php");
// Start session
session_start();
// Check if user is logged and existing session
if(isset($_SESSION['logat'])) {
// Content for user logged
echo "Welcome ".$user." :) - <a href='logout.php'>Logout</a>";
} else {
// Redirecting to login page
Header("Location: ./");
}
?>
Always put session_start() as the very first statement after <?php
It is okay to run session_start() even if the user is not logged in. session_start() should be the first statement.
Note that the header() command requires a lowercase h (not Header - that is wrong).
index.php
<?php
session_start();
include("config.php");
// Check form if is submited
if( isSet($_POST['user']) ) {
// Check if user is equal with username and password from config.php
if($_POST['user'] != $user || $_POST['pass'] != $pass) {
echo "Sorry, your data is invalid";
} else {
// Open the session for store user logged
// Setting the session
$_SESSION['logat'] = "da";
$_SESSION['username'] = $_POST['user'];
// Redirecting user to admin page if is logged
header('Location: admin.php');
}
} else {
// Form
$out = '
<form action="" method="post">
Username: <input type="text" name="user">
Password: <input type="password" name="pass">
<input type="submit" name="trimite">
</form>
';
echo $out;
}
?>
admin.php -- Here is how to reference/use the username session variable:
<?php
// Start session
session_start();
include("config.php");
// Check if user is logged and existing session
if(isset($_SESSION['logat'])) {
// Content for user logged
echo "Welcome ".$_SESSION['username']." :) - <a href='logout.php'>Logout</a>";
} else {
// Redirecting to login page
header("Location: ./");
}
?>
Note that header can only be used if no data has been sent to the DOM yet. Sometimes that is very difficult to prevent. Here is an HTML tag that allows you to redirect to another page:
<meta http-equiv="refresh" content="0;url=http://example.com">
The number zero (before url= means the number of seconds to wait before redirecting the page.

How to create a very simple username - password login in PHP?

index.php
<?php
if( $_SESSION['auth'] != 1 ) {
require( 'login.php' );
}
else {
echo "hello";
}
?>
login.php
<?php
$name = $_POST['name'];
$pass = $_POST['pass'];
if( isset($name) || isset($pass) )
{
if( empty($name) ) {
die ("ERROR: Please enter username!");
}
if( empty($pass) ) {
die ("ERROR: Please enter password!");
}
if( $name == "<some name>" && $pass == "<some password>" )
{
// Authentication successful - Set session
session_start();
$_SESSION['auth'] = 1;
setcookie("username", $_POST['name'], time()+(84600*30));
echo "Access granted!";
}
else {
echo "ERROR: Incorrect username or password!";
}
}
// If no submission, display login form
else {
?>
<html>
<head></head>
<body>
<center>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
Username: <input type="text" name="name" value="<?php echo $_COOKIE['username']; ?>">
<p />
Password: <input type="password" name="pass">
<p />
<input type="submit" name="submit" value="Log In">
</center>
</body>
</html>
<?php
}
?>
So, as I'm still learning PHP, there's a few things I'm trying to figure out now:
How do I get it so I can reload index.php and it displays 'hello'?
How can I get login.php to auto-load index.php on a successful authentication so I can get it to that "hello"?
Later, would using a cookie to store the user's submitted login data (so they don't have to refill the form to restore their session) have any potential problems?
Help appreciated.
1, You're missing session_start() in index.php. Add it and you should be able to see 'Hello world'
2, Replace your line with "Access granted!" with a redirect:
header('Location: index.php');
exit;
3, You can definitely store credentials in a cookie, but you should always hash and salt the password. Here is a good article about password hashing.
Better way of doing things:
Check for the session variable in the index.php and redirect if it is not set. Something like this
session_start();
if (!isset($_SESSION['auth']) || $_SESSION['auth'] != 1) {
header('Location: login.php');
exit();
}
echo 'Hello';
In the login.php, after successful authentication, redirect to index.php and do the echo there.
session_start();
if( $name == "<some name>" && $pass == "<some password>" )
{
// Authentication successful - Set session
$_SESSION['auth'] = 1;
setcookie("username", $_POST['name'], time()+(84600*30));
header('Location: index.php');
exit();
}
else {
echo "ERROR: Incorrect username or password!";
}
session_start() should come before any content is echoed to the browser.
You should:
always try to call session_start() as early as possible - "To use cookie-based sessions, session_start() must be called before outputing anything to the browser."
check whether $_POST['name'] isset before doing $name = $_POST['name'];. You can do:
$name = isset($_POST['name']) ? $_POST['name'] : '';
store the username directly in $_SESSION so that cookie holds only PHPSESSID and no data that could be replaced / abused by the end users:
$_SESSION['user'] = 'John';
try to redirect the user to index.php to see the immediate result of changing the session:
header('Location: index.php');
exit;
So this is how it could look like:
<?php
session_start();
if (empty($_SESSION['user'])) {
$name = isset($_POST['name']) ? $_POST['name'] : '';
$pass = isset($_POST['pass']) ? $_POST['pass'] : '';
if ($name != '' || $pass != '')
{
if ($name === '')
die("ERROR: Please enter the username!");
if ($pass === '')
die("ERROR: Please enter the password!");
if ($name == "test" && $pass == "test") {
// authentication successful, save username in session:
$_SESSION['user'] = 'John';
// redirect to index.php to welcome the logged in user:
header('Location: index.php');
exit;
}
else {
die("ERROR: Incorrect username or password!");
}
}
// no submitted data, display form:
?>
<html>
<head></head>
<body>
<center>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
Username: <input type="text" name="name" value=""><br>
Password: <input type="password" name="pass"><br>
<input type="submit" value="Log In">
</form>
</center>
</body>
</html>
<?php
}
else {
// info about current user is stored in session, welcome this user:
echo "hello " . $_SESSION['user'];
}
?>
Use this to redirect to index.php (I hope it answers your #1 and #2)
if( $name == "<some name>" && $pass == "<some password>" )
{
// Authentication successful - Set session
session_start();
$_SESSION['auth'] = 1;
setcookie("username", $_POST['name'], time()+(84600*30));
//echo "Access granted!";
header("Location: index.php");
die('');
}
You are using cookies to store the username directly. That is not a great option. What if a user modifies the cookies, to read some other username? Instead use $_SESSION['..']
Like this:
$_SESSION['user']=$_POST['name'];
and then later on,
if (isset($_SESSION['user']))
echo "Hello, " . $_SESSION['user'];
How do I get it so I can reload index.php and it displays 'hello'?
Remove the else, so it will always display the "hello":
if($_SESSION['auth'] != 1) {
require('login.php');
}
// Either way always print.
echo "hello";
How can I get login.php to auto-load index.php on a successful authentication so I can get it to that "hello"?
Replace echo "Access granted!"; with header('Location:index.php');
Later, would using a cookie to store the user's submitted login data (so they don't have to refill the form to restore their session) have any potential problems?
As long as are using this as a way to autofill the username only. and require the users to enter their password every time. otherwise a user can set his username cookie to "admin" or some other user.
no one is mentioning that you should check that the session is actually a valid one... if you just check it's set you can most likley fake it and get through.
also to hash credentials into the cookie i would encrypt it first server side and then hash it. just in case somewhere in the future someone breaks the hash type. sha3-256 is your best choice here as it's not known to be broken and should resist alot of computing power increase in the future.
What i usually do is to encrypt password and user with the user password itself as key, that way, if you also store their credentials in this fasion in your own database, there is no way even for the site maintainer to decrypt it and steal the passwords. and any db dumping skiddie will have only some meta data. (you should also encrypt the usernames...)
It seems a little conveluted to be a 'simple login and password for the users' but really as simple as possible should still consider security for your users, even if it's not a public site...
So remember:
check sessions and cookies for valid contents if they are there
check user and pw input fields for sane data before forwarding to your auth process.
encrypt user and pw information in your server side, and in the client side if you send it there (cookies?).
use AES256 atleast (mysql support this native since 5.6 its really easy to use...) for encrypting data.
use sha3-256 for hashing.
look at guides for crypto and hashing as it's easy to mess up.
ask a friend in the know to test your setup to best of their ability for a crate of beer ^^ and have fun with him and learn a bunch of stuff about your code :D
lastly, i will have forgotten (or don't know atall) alot of stuff, so there will be missing bullets! :D

Categories