I have one serious problem.
There is a little PHP system, which contains admin panel and customer panel.
These panels must be functioning independently from each other.
For example - if admin logs out, customer must stay inside, etc.
There is my logout.php script (which is called by logout button javascript handler):
<?php
require_once("./setup/additional_functions.php");
require_once("./setup/mysql_settings.php");
session_start();
$functionName = filter_input(INPUT_GET, "functionName");
if($functionName == "logoutAdmin") {
initiateLogout("um_status", "users_managers", "um_id", $_SESSION['admin_id'], "admin");
} else if($functionName == "logoutCustomer") {
initiateLogout("customer_visit", "users_customers", "customer_id", $_SESSION['cust_id'], "../customer");
} else {
echo "Unknown error!";
}
function initiateLogout($loginTime, $tableName, $id, $sessionName, $backPage) {
$sqli = new sqlSettings();
$sql = "SELECT ". $loginTime ." FROM ". $tableName ." WHERE ". $id ." = ". $sessionName;
$result = $sqli->setConnection()->query($sql);
$user = $result->fetch_array();
$timestamp = $user[$loginTime] - 300;
$sql = "UPDATE " .$tableName. " SET " .$loginTime ." = ". $timestamp. " WHERE " .$id ." = ". $sessionName;
$result = $sqli->setConnection()->query($sql);
$_SESSION = array();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 50000, '/');
}
unset($sessionName);
//redirect_to($backPage);
echo "../" . $backPage;
}
?>
Data inside $_SESSION['admin_id'] and $_SESSION['customer_id'] - absolutely different! But anyway - when I hit button (for example) on admin side - customer also logs out!!! It shouldn't be like this.
How to avoid this? Will be very thankful for any help!!
You don't need to be setting $_SESSION to an empty array.
You need to be setting the respective $_SESSION key to null or insetting it.
For customers this would be unset($_SESSION['cust_id']) and for admin this would be unset($_SESSION['admin_id'])
Your current code destroys the whole session which logs both customer and admin accounts out.
Well, I think my mistake was in testing whole system on my local computer. Cause if you do the same - session is being created during one browser and one pc. And it doesn't matter by whom you're logged in. After I placed my system on remote server and tested my old code from different "points" - everything works perfect.
Related
I have a first site https://www.mydomain1.com in which I use PHP sessions. No problem, everything works fine, when I go from page to page, I can access my session variables.
I have a second site https://www.mydomain1.com in which I display part of my 1st site via an iframe:
<iframe src = "https://www.mydomain1.com" width = "100%" frameborder = "0" style = "border: 0" allowfullscreen = "allowfullscreen" id = "frameLeonard"> </iframe>
And there strangely, the session variables are no longer recognized. I'm not even trying to get my 1st site to access the session variables from the 2nd site (that's not the goal and it's normal that it doesn't work) but just run the 2nd site inside the 1st site.
Strangely, it was still working a year ago.
Has there been any upgrade that would explain the problem?
Thank you in advance for your lights !
Now I found the reason, chrome shows this behaviour. With version 80 (Feb. 2020) it has it's "SameSite by default cookies" enabled as default, which means that including external pages (different domain) inside an iframe, will kill their sessions.
For preventing this, you can disable "SameSite by default cookies" in chrome://flags
Beware: This might be a security issue (but solved my problem for now)
Otherwise - if using PHP 7.3 or newer - you could add one (or both) of the following ini_set() in your PHP before session_start():
ini_set('session.cookie_samesite', 'None');
session_set_cookie_params(['samesite' => 'None']);
Here you get further details:
https://blog.heroku.com/chrome-changes-samesite-cookie#prepare-for-chrome-80-updates
i recommend you use MySQL function for that,
// to add captcha record via img file.
$time = time();
$deltime = time()-1500;
$ip = $_SERVER['REMOTE_ADDR'];
$result = $conn->query("SELECT * FROM `captcha` WHERE `ip` = '" . $ip . "'");
if (($result) && ($result->num_rows >= 1))
{
$conn->query("UPDATE `captcha` SET `captcha` = '".$_SESSION["captcha"]."' WHERE `ip` = '".$ip."'");
}
else
{
$conn->query("DELETE FROM `captcha` WHERE `time` < '".$deltime."'");
$sql = "INSERT INTO `captcha` (captcha, ip, time) VALUES ('".$_SESSION["captcha"]."', '".$ip."', '".$time."')";
if ($conn->query($sql) === TRUE) {
//echo "New record created successfully";
} else {
//echo "Error: " . $sql . "<br>" . $conn->error;
}
}
// on process file to match captcha code
$ip = $_SERVER['REMOTE_ADDR'];
$result = $conn->query("SELECT * FROM `captcha` WHERE `ip` = '" . $ip . "'");
while ($row = $result->fetch_assoc())
{
$captcha = $row['captcha'];
}
if ($captcha == $_POST["access_token"]) { /* do anything */ }
Having the same problem here, but no solution yet.
I made several tests. Seems only to occur, when iFrame loaded content is SSL certificated. If not, it works perfect.
Maybe this is helpful. Or did you get any solution yet?
I´m trying to redirect visitor when visits the page for first time to site 1. The second visit the script will redirect the visitor to site 2. I want to use session. But it doesn´t work right and I dont know where is the mistake.
Logic should be: If you are here for the first time you will be redirected to site 1, if you are here for the second time you will be redirected to side 2.
this is the code i made:
session_start();
if ($_SESSION["header"] = " " || !isset($_SESSION))
{
$_SESSION["header"] = "1";
echo header("Location: http://site 1");
}
else
{
session_destroy();
echo header("Location: http://site 2");
exit();
}
well I´m not sure if the session is the right way how to do it
Thanks a lot.
It's not possible and not recommended to do it with a session. Because after a while the session gets destroyed automatically.
I rather you to use cookies.
The code is similar to your code. The only difference between sessions and cookies is that cookies can be setted for lifetime
You're using this code which is wrong.
$_SESSION["header"] = " "
$_SESSION["header"] = " " means to assign ' ' to $_SESSION["header"]
It should be:
$_SESSION["header"] == " "
$_SESSION["header"] == " " means $_SESSION["header"] is equal to ' '
== is for comparison, = is for assignment, and === is for identical or same type.
More information at http://php.net/manual/en/language.operators.comparison.php.
Logging in we of course have set the $_SESSION['username'] and $_SESSION['password'] as usual. However I am then trying to pack that into a variable for use around the site:
$logged = mysql_query("SELECT * FROM `users` WHERE `username`='$_SESSION['username']' AND password = '$_SESSION['password']'");
$logged = mysql_fetch_array($logged);
One previous setups, this has enabled me to then use $logged around the site for various reasons, such as calling the logged in users email to echo in a form,
However, this time, when using this method, it fails to echo anything. I have tried using the session username variable which works to echo the username, but then I tried using the session to echo the email and it didn't work.
If someone could help me pinpoint why this is, I'd be grateful.
It just doesn't seem to be pulling any information from the user as it should.
For me this just seems like an escape-thing. Try
$logged = mysql_query("SELECT * FROM users WHERE username='".$_SESSION['username']."' AND password = '".$_SESSION['password']."'");
$logged = mysql_fetch_array($logged);
Also make sure to call session_start(); before sending any headers/echoing anything if you weren't aware.
Off topic-tip
As long as this query isn't used in anything public, it's fine. But if you're gonna use this code for anything, be sure to slash your query variables. If not, and if my credentials are not validated nor hashed, you could do some nasty SQL injection by setting your password to be something like '; DELETE * FROM USERS;# as the query would then say SELECT * FROM users WHERE username='JohnDoe' AND password = ''; DELETE * FROM USERS;#'
for the usage of session
if(!session_id())
session_start();
the above session start is a must in every page.
use print_r($_SESSION); to check the session variables initialized..
once done (try using mysqli insted of mysql)
$sql='SELECT col1, col2, col3 FROM table1 WHERE condition';
$rs=$conn->query($sql);
if($rs === false) {
trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);
} else {
$arr = $rs->fetch_all(MYSQLI_ASSOC);
}
foreach($arr as $row) {
echo $row['co1'];
}
comment your progress for further changes..
First of all, I am testing on localhost. I have this index.php file which contains the following "remember me" checkbox:
<input type="checkbox" id="login_remember" name="login_remember">
The login form posts to loginvalidate.php, which includes the following php script. I have included a lot of comments to ease the process of reading my code. Note that I'm pretty sure that everything below works fine.
if (isset($_POST['login_submit'])) { //SETS VARIABLES FROM FORM
$email = $_POST[trim('login_email')];
$password = $_POST['login_password'];
$remember = isset($_POST['login_remember']) ? '1' : '0';
$db_found = mysqli_select_db($db_handle,$sql_database); //OPENING TABLE
$query = "SELECT password FROM registeredusers WHERE email = '$email'";
$result = mysqli_query($db_handle, $query) or die (mysqli_error($db_handle));
$row = mysqli_fetch_assoc($result);
$numrows = mysqli_num_rows($result);
if ($numrows!=0) //IF EMAIL IS REGISTERED
{
if ($row['password'] == $password) { //IF PASSWORD IN DATABASE == PASSWORD INPUT FROM FORM
if ($remember == '1'){ //IF USER WANTS TO BE REMEMBERED
$randomNumber = rand(99,999999); //RANDOM NUMBER TO SERVE AS A KEY
$token = dechex(($randomNumber*$randomNumber)); //CONVERT NUMBER TO HEXADECIMAL FORM
$key = sha1($token . $randomNumber);
$timeNow = time()*60*60*24*365*30; //STOCKS 30 YEARS IN THE VAR
$sql_database = "registeredusers";
$sql_table = "rememberme";
$db_found = mysqli_select_db($db_handle,$sql_database); //OPENING TABLE
$query_remember = "SELECT email FROM rememberme WHERE email = '$email'"; //IS THE USER IN TABLE ALREADY
$result = mysqli_query($db_handle, $query_remember) or die (mysqli_error($db_handle));
if (mysqli_num_rows($result) > 0) { //IF USER IS ALREADY IN THE REMEMBERME TABLE
$query_update = "UPDATE rememberme SET
email = '$email'
user_token = '$token'
token_salt = '$randomNumber'
time = '$timeNow'";
}
else { //OTHERWISE, INSERT USER IN REMEMBERME TABLE
$query_insert = "INSERT INTO rememberme
VALUES( '$email', '$token', '$randomNumber', '$timeNow' )";
}
setcookie("rememberme", $email . "," . $key, $timenow);
}
header('Location: homepage.php'); //REDIRECTS: SUCCESSFUL LOGIN
exit();
}
Then, when I close the internet browser and come back to index.php, I want the cookie to automatically connect the user. This is in my index.php:
include 'db_connect.php';
$sql_database = "registeredusers";
$db_found = mysqli_select_db($db_handle,$sql_database); //OPENING TABLE
session_start();
if (isset($_COOKIE['rememberme'])) {
$rememberme = explode(",", $_COOKIE["rememberme"]);
$cookie_email = $rememberme[0];
$cookie_key = $rememberme[1];
$query_remember = "SELECT * FROM rememberme WHERE email = '$cookie_email'"; //IS THE USER IN TABLE ALREADY
$result_remember = mysqli_query($db_handle, $query_remember) or die (mysqli_error($db_handle));
$row = mysqli_fetch_assoc($result_remember);
$token = $row['user_token'];
$randomNumber = $row['token_salt'];
$key = sha1($token . $randomNumber); //ENCRYPT TOKEN USING SHA1 AND THE RANDOMNUMBER AS SALT
if ($key == $cookie_key){
echo "lol";
}
}
The problem is, it never echoes "lol". Also, does anyone have any insight on how I could connect the users? AKA, what should go inside these lines:
if ($key == $cookie_key){
echo "lol";
}
Thank you! I'm still new to PHP and SQL so please bear with me if I have made some beginner errors.
EDIT!: After looking again and again at my code, I think that my error might lie in these lines. I'm not sure about the syntax, and the method I am using to store values into $token and $randomNumber:
$query_remember = "SELECT * FROM rememberme WHERE email = '$cookie_email'"; //IS THE USER IN TABLE ALREADY
$result_remember = mysqli_query($db_handle, $query_remember) or die (mysqli_error($db_handle));
$row = mysqli_fetch_assoc($result_remember);
$token = $row['user_token'];
$randomNumber = $row['token_salt'];
A login script in PHP can be implemented using sessions.
Using Sessions
Making it simple, sessions are unique and lives as long as the page is open (or until it timeouts). If your browser is closed, the same happens to the session.
How to use it?
They are pretty simple to implement. First, make sure you start sessions at the beginning of each page:
<?php session_start(); ?>
Note: It's important that this call comes before of any page output, or it will result in an "headers already sent" error.
Alright, now your session is up and running. What to do next? It's quite simple: user sends it's login/password through login form, and you validate it. If the login is valid, store it to the session:
if($validLoginCredentials){
$_SESSION['user_id'] = $id;
$_SESSION['user_login'] = $login;
$_SESSION['user_name'] = $name;
}
or as an array (which I prefer):
if($validLoginCredentials){
$_SESSION['user'] = array(
'name' => $name,
'login' => 'login',
'whichever_more' => $informationYouNeedToStore
);
}
Ok, now your user is logged in. So how can you know/check that? Just check if the session of an user exists.
if(isset($_SESSION['user_id'])){ // OR isset($_SESSION['user']), if array
// Logged In
}else{
// Not logged in :(
}
Of course you could go further, and besides of checking if the session exists, search for the session-stored user ID in the database to validate the user. It all depends on the how much security you need.
In the simplest application, there will never exist a $_SESSION['user'] unless you set it manually in the login action. So, simply checking for it's existence tells you whether the user is logged in or not.
Loggin out: just destroy it. You could use
session_destroy();
But keep in mind that this will destroy all sessions you have set up for that user. If you also used $_SESSION['foo'] and $_SESSION['bar'], those will be gone as well. In this case, just unset the specific session:
unset($_SESSION['user']);
And done! User is not logged in anymore! :)
Well, that's it. To remind you again, these are very simple login methods examples. You'll need to study a bit more and improve your code with some more layers of security checks depending on the security requirements of your application.
reason behind your code is not working is
setcookie("rememberme", $email . "," . $key, $timenow); // this is getting expire exactly at same time when it is set
replace it with
setcookie("rememberme", $email . "," . $key, time() * 3600);//expire after 1hour
time()*60*60*24*365*30
this time is greater than 9999 year also you didn't need to set this horror cookie time.
that cookie time you were set is greater than 9999 years and php not allow for this configure.
in my opinion the best solution is setup new expire cookie time lower than 9999 :))
I use the following piece of code in an include file. Because it it used in two instances within my code, I wanted to separate it into another include file and use with require_once() where it is needed. However, I noticed that if I do that, the cookies won't set. Everything else seems to work though. Is this a bug or this just can't be done this way.
I have been learning PHP only for two weeks so please take it easy on me.
Thank you!
if(mysqli_num_rows($checklogin) == 1)
{
// set variables
$row = mysqli_fetch_array($checklogin);
$email = $row['Email'];
// create login sessions
$_SESSION['UserName'] = $username;
$_SESSION['Email'] = $email;
$_SESSION['LoggedIn'] = 1;
$cbxRememberMe = $_POST['cbxRememberMe'];
// if remember me is checked
if(isset($cbxRememberMe) && $cbxRememberMe == '1')
{
$row = mysqli_fetch_array($checklogin);
// create cookies for autologin
$expire = time() + AUTO_LOGIN_DURATION;
$cookie_un = sha1(sha1($row['UserName']));
$cookie_pass = sha1(sha1($row['Password']));
setcookie('user', $cookie_un, $expire);
setcookie('pass', $cookie_pass, $expire);
}
// get user's IP address
$lastloginip = $_SERVER['REMOTE_ADDR'];
// DB QUERY: update database activity
// ------------------------------------------------------------------
$updateactivity = mysqli_query($conn,"UPDATE users SET LastLoginDate = NOW(), LastActivityDate = NOW(), LastLoginIP = '$lastloginip' WHERE UserName = '$username'")
or die($updateactivity_error);
// ------------------------------------------------------------------
// redirect back to login to refresh
header('Location: login.php');
}
A require()/include()'d file will execute exactly the same as if its contents had been embedded in the file doing the require/include. A cookie header looks exactly the same whether it's directly in a file, or done via an inclue.
I'd look at whether you've actually done a mysqli query before the require once line, since you've wrapped the entire include with that if (mysqli_num_rows(... business. Perhaps you should move the query definition/execution business into the include file as well.