i'm learning to use cookies in PHP. I was expecting that every time i set a cookie, the cookie and all of his variables are stored on the client site so i could use them again next time the user will visit the site. Anyway in the next example (a web application with a sign in option, i use cookies to store a unique string so i could implement "Remember me" option) i can access the id of the stored cookie but the variables data seem lost. Here is example of the code i use and screenshots of what i get.
Setting up a Cookie
if (isset($_POST['remember_me'])) {
$token=uniqid($_SESSION['id']);
$sql="UPDATE users SET token='$token' WHERE id='".$_SESSION['id']."'";
$conn->query($sql);
setcookie("remember_me", $token, time()+30*24*60*60*1000);
}
else{
setcookie("remember_me","",time()-1000);
}
User page
On the user page it just simply prints out the $_COOKIE and $_SESSION array.
<?php
echo "SESSION: ";
print_r($_SESSION);
?>
<br>
<?php
echo "COOKIE: ";
print_r($_COOKIE);
?>
Process:
First i delete all the cookies using the advice i found here:
how to delete all cookies of my website in php
Then log inside Log in screen (this form call a script that execute the code for setting a cookie i gave at the beginning, then redirect to the user-page) User page before closing
Close the browser and open it again directly at the user-page (without executing other scripts /localhost/MIAFormApp/script/db/HTML_PROBA/user-page.html.php User page after re-opening
What did i get wrong and why the cookies array after re-opening is empty?
EDIT:
The second time i open browser the script for seting the cookie is not executed. I just set the url to go to the user-page.php .
Examp:
/localhost/MIAFormApp/script/db/HTML_PROBA/user-page.html.php
Try deleting the else statement in your sample code - meaning go from:
This
if (isset($_POST['remember_me'])) {
$token=uniqid($_SESSION['id']);
$sql="UPDATE users SET token='$token' WHERE id='".$_SESSION['id']."'";
$conn->query($sql);
setcookie("remember_me", $token, time()+30*24*60*60*1000);
}
else{
setcookie("remember_me","",time()-1000);
}
To this
if (isset($_POST['remember_me'])) {
$token=uniqid($_SESSION['id']);
$sql="UPDATE users SET token='$token' WHERE id='".$_SESSION['id']."'";
$conn->query($sql);
setcookie("remember_me", $token, time()+30*24*60*60*1000);
}
When you re-open your browser, the if statement is going to check whether or not the POST variable remember_me was found. The only time that it will be found is when someone logs in because the login form is sending that information on form submit. In every other instance ( such as re-opening the browser), the else statement will be executed which isn't what you want. The reason being that setting an empty value on a cookie will delete said cookie.
Related
I have a website that use mercadopago payments (similar to PayPal, from South America).
When user finish payment and is redirected back to my site, I get a new session id and I am not able to read old one, also not able to read previously set cookies.
My problem is that I need cookie or session value to keep user logged in, if not, I need to ask user and password again and the client does not like that.
This is the code that I am using to set the cookies, with comments explaining my problem:
<?php
session_start();
include("db-connection.php");
if(isset($_SESSION["id_alumno"]))
{
$sid=session_id();
if(isset($_COOKIE["user_token"])){
//just for debbuging
//echo "user_token is a " . $_COOKIE["user_token"];
}else{
//set cookie and update same value in database
setcookie("user_token", $sid, time()+2*24*60*60);
$id_alumno=$_SESSION["id_alumno"];
$sql="UPDATE `alumno` SET `login_token` = '$sid', `login_creado` = NOW() WHERE `alumno`.`id` = '$id_alumno'";
$res=mysqli_query($link, $sql); //this connection values are send in a db-connection.php already included.
}
}else{
$cookie_value=$_COOKIE["user_token"]; // here is my problem, I can't access this value, checking cookie information using chrome and the plugin web developer, I get 2 PHPSESSID (old which was used to set cookie with user_token, and also the user token value, and also this new PHPSESSID)
if(isset($cookie_value)){
$sql="SELECT * FROM alumno where login_token='$cookie_value' and login_token!='no'";
$res=mysqli_query($link, $sql);
if($reg=mysqli_fetch_array($res))
{
//here I can login back the user
}//mysql query
}//if isset cookie value
}
?>
You're using session_start() with it's default options. As soon as you leave your site the session cookie expires.
Try example #3 from the manual:
<?php
// This sends a persistent cookie that lasts a day.
session_start([
'cookie_lifetime' => 86400,
]);
?>
This sends a persistent cookie that lasts a day.
See also: How do I create persistent sessions in PHP?
On my secure site (https), I set a PHP $_SESSION variable. I then use header("location: http://...page.php") to send the user to a php page on my http site, which is on the same server. The session variable is lost, because of the http:// URL (I assume) in the header statement. I can't get the header("location: ...") to work without using the full URL. Thus I tried the following tip from stackoverflow - php session lost when switching, which several other posts reference, but I ended up with numerous error_log warning entries and once I clicked to another page that required $_SESSION['loginUser'], the session was gone.
PHP Warning: session_start(): The session id is too long or contains illegal characters
Sample session ID passed: dlouenopfi3edoep3dlvne8bn1
Code that creates the session on https php page (note for this post header location is not real)
session_start();
$currentSessionID = session_id();
$_SESSION['loginUser'] = $username;
header("location: http://www.test.com/path/to/page/off-campus/cat_index.php?session=$currentSessionID");
Code that receives the session on http php pages
// Retrieve the session ID as passed via the GET method.
$currentSessionID = $_GET['session'];
echo "sid: " . $currentSessionID;//a session id like above is displayed
// Set a cookie for the session ID.
session_id($currentSessionID);
session_start();
if(isset($_SESSION['loginUser'])){
$username = $_SESSION['loginUser'];
echo "Welcome: $username<br />";
} else {
require_once($_SERVER["DOCUMENT_ROOT"] . "/_includes/CASwrap.php");
}
I've exhausted my searching. Any help will be appreciated. Thanks.
I solved my two questions.
To prevent the numerous error_log warning entries all I needed was an "exit" statement after the "header" statement.
To maintain the current session, I used an if statement to test for a current session id stored in the variable $currentSessionID. If yes then set the session_id with the value of $currentSessionID. If no, then don't set the session_id with the $currentSessionID variable, since it has no value.
I can't seem to find a straightforward answer to this question. Is there a way in which I can force a logged in user to logout? My login system essentially just relies on a session containing the user's unique ID (which is stored in a mysql database). So essentially just...
if (isset($_SESSION['user_id'])) {
echo "You're logged in!";
} else {
echo "You need to login!";
}
But let's say I want to ban this user, well I can change their status to banned in my database but this won't do anything until the user logs out and attempts to log back in... So, how do I force this user to logout? Preferably without checking every single time they view a page whether or not their status has been switched to "banned" because that seems like unnecessary stress on my server. Any help is appreciated, thank you.
Either you need to check every time they load a page, or possibly look at an Ajax call at set intervals to check their status from the DB.
Then you can use session_destroy(); to end their session. This will destroy their entire session.
Otherwise you can use unset($_SESSION['user_id']); to unset a single session variable
Preferably without checking every single time they view a page whether or not their status has been switched to "banned" because that seems like unnecessary stress on my server.
Loading the user from the database on every page load, rather than storing a copy of the user in the session, is a perfectly reasonable solution. It also prevents the user from getting out of sync with the copy in the database (so that, for instance, you can change a user's properties or permissions without them having to log out and back in).
Try to put this on every page...
if (isset($_SESSION['user_id'])) {
$sql = "SELECT from tbl where status='banned' and user_id=$_SESSION['user_id'] ";
$query = mysql_query($sql);
if(!empty(mysql_num_rows($query))){ // found the banned user
//redirect to logout or
//session_destroy();
}
} else {
echo "You need to login!";
}
if the user is still logged in... check if his/her status is banned or not... if banned.. then logout
You can unset it.
unset($_SESSION['user_id'])
You could use Custom Session Handlers this way you have full control where and how the session data is stored on the server.
So you could store the session data for a particular user in a file called <user_id>.session for example. Then, to logout the user, just delete that file.
Ajax calls in an interval will put extra load on server. If you want real-time response to your actions(e.g. the user will be signed out right when you ban them from your system backend), then you should look into something like Server Push.
The idea is to keep a tunnel open from Server to Browser whenever a user is browsing your website, so that you can communicate with them from server-side too. If you want them to be banned, push a logout request and the process that in your page(i.e. force logout by unsetting session).
This worked for me am using pHP 5.4
include 'connect.php';
session_start();
if(session_destroy())
{
header("Location: login.php");
}
You can use session_save_path() to find the path where PHP saves the session files, and then delete them using unlink().
Once you delete the session file stored in the sever, the client side PHPSESSID cookie will no longer be valid for authentication and the user will be automatically be logger out of your application.
Please be very careful while using this approach, if the path in question turns out to be the global /tmp directory! There's bound to be other processes other than PHP storing temporary data there. If PHP has its own directory set aside for session data it should be fairly safe though.
There is a few ways to do this the best in my opinion based on security is:
NOTE: THIS IS REALLY ROUGH.... I know the syntax is wrong, its just for you to get an idea.
$con = mysql_connect("localhost","sampleuser","samplepass");
if (!$con)
{
$error = "Could not connect to server";
}
mysql_select_db("sampledb", $con);
$result = mysql_query("SELECT * FROM `sampletable` WHERE `username`='".$_SESSION['user_id']."'");
$userdeets = mysql_fetch_array($result);
if($_SESSION['sessionvalue'] != $userdeets['sessionvalue'])
{
session_destroy();
Header('Location: logout.php');
}
else
{
$result2 = mysql_query("UPDATE `sessionvalue` WHERE `username`='".$_SESSION['user_id']."' SET `sessionvalue` = RANDOMVALUE''");
$sesval = mysql_fetch_array($result2);
$_SESSION['sessionvalue'] = $seshval
}
Now I know thats not the very code but in essence what you need to do to be secure and have this ability is:
Everytime a page load check a Session value matches a value in the DB.
Every time a page loads set a new session value based on a random generated DB value. you will need to store the username in a session as well.
if the Session ID's do not match then you destroy the session and redirect them.
if it does match you make the new session ID.
if you want to ban a user you can set their sessionvalue in the DB to a value like "BANNED". this value will not allow them to log in either. this way you can control user through a simple web form and you can also generate list of banned users very easily etc etc. I wish I had more time to explain it I hope this helps.
I have a question about PHP sessions. I use a session to keep a visitor logged in. I have made a site before with this and works perfect. Now I am making a Facebook app.
When logging in (checking if user is registered in database), I register id. After that I use:
if(session_is_registered("id"))
{
echo "Logged in";
}
So if it shows "Logged in" in the browser, I am absolutely sure that the session is registered. But when I go to the next page (which has session_start(); at the top of the page), there's no session anymore. But if I go to the logout page (with session_destroy();), and then proceed to the login, the session is registered correctly. Also if I close all the browser windows and then go to login, it won't register correctly.
I tried destroying the session right before registering the 'id', but that also doesn't work.
I'm guessing I made a basic error, so someone on here should be able to help me without wasting a lot of time.
Please help me. I have wasted days on this.
Thanks in advance.
More code:
Where session is registered:
$id_query = mysql_query ("
SELECT * FROM Tour11_deelnemers WHERE fb_id = '$user'");
while ($record = mysql_fetch_assoc ($id_query))
{
$id = $record['deelnemer_id'];
}
if($id > 0)
{
$speelid = $id;
session_register("speelid");
}
After that to check if it is registered:
if(session_is_registered("speelid"))
{
echo "Ingelogd";
}
session_is_registered() is same as isset() for $_SESSION.
So the thing I don't understand is while session_is_registered() is true after it is registered, on the next page it is false again :( unless I login immediately after going to logging out page (session_destroy();). So even if i destroy the session just before restarting it and registering again, it doesn't help.
Here is a solution for you.
Set the session like this:
if(!isset($_SESSION['speelid'])){
$id_query = mysql_query ("SELECT * FROM Tour11_deelnemers WHERE fb_id = '$user'");
while ($record = mysql_fetch_assoc ($id_query)){
$id = $record['deelnemer_id'];
}
if($id > 0){
$_SESSION['speelid'] = $id;
}
}
Check if a session is set like this:
if(isset($_SESSION['speelid'])){
echo "Ingelogd";
}
Update
It seems like the issue is related to >= IE6 refusing to accept the session cookie generated by the php, when a .php file is referred from an .html file on a different server.
.HTML to .PHP session IE issue
When using session
variables in a .php file referred by a
frame (.html, or other file type) at a
different server than the one serving
the .php:
Under these conditions IE6 or later
silently refuses the session cookie
that is attempted to create (either
implicitly or explicitly by invoquing
session_start()).
As a consequence, your session
variable will return an empty value.
According to MS kb, the workaround is
to add a header that says your remote
.php page will not abuse from the fact
that permission has been granted.
Place this header on the .php file
that will create/update the session
variables you want:
Here is a full thread on this issue
Solution
The solution is to add this at the very top of the page which will SET the session.
<?php header('P3P: CP="CAO PSA OUR"'); ?>
Greetings,
Been going around in circles trying to figure out why this will not work. Making a low security log-in system using cookies due to an issue with sessions on the device being used. The set cookie works on its own but either is not setting properly in this script or is not being read properly on the auth script. Also, after the cookie should be set, it is not in the browser. Ideas??
Login
<?php
//If passwords match, a cookie is created
if ($pw = $hashedpw) {
$memberID = "1221"; //Pulled from DB
setcookie('MDADMIN_SESS_ID',$memberID,'0','', '.somewhere.com');
header('Location: http://somewhere.com/secure_page.php');
}
?>
Auth
<?php
//Verify that cookie is present
$cookie = $_COOKIE['MDADMIN_SESS_ID'];
if(!isset($cookie)) {
header("Location: http://somewhere.com/failed.php");
exit();
}
?>
The process is as follows: Login Form -> Login Script -> Secure Page (if passwords match) -> Auth Script checked (via include) -> redirect to failed login if cookie not present. When run, it always defaults to the cookie not being present, even though the login script correctly directs to the secure page (logged in successfully).
try
<?php
//If passwords match, a cookie is created
if ($pw = $hashedpw) {
$memberID = "1221"; //Pulled from DB
setcookie('MDADMIN_SESS_ID',$memberID,'0','/', '.somewhere.com');
header('Location: http://somewhere.com/secure_page.php');
exit();
}
?>
You are missing a / for the path.
Also make sure you have an exit(); function after the header; because if you unset the cookie later at someplace then it might also get affect.
try to add / to this line (in $path variable) If set to '/', the cookie will be available within the entire domain
setcookie('MDADMIN_SESS_ID',$memberID,'0','/', '.somewhere.com');