Is it possible to unset a specific user session (one who is banned from the site)?
Each session contains the user's username.
Or is the only way to writing sessions in the database and checks whether the user is deleted from that record?
Thanks for any suggestion.
PHP doesn't keep track of what session IDs have been issued - when a session cookie comes in on a request and session_start() is called, it'll look in the session save directory for a file named with that session's ID (sess_XXXX) and load it up.
Unless your login system records the user's current session ID, you'll have to scan that save directory for the file that contains the user's session, and delete the file. Fortunately, it could be done with something as simple as:
$session_dir = session_save_path();
$out = exec("rm -f `grep -l $username $session_dir/*`");
You'd probably want something a bit more secure/safe, but that's the basics of it.
Just remove the user from your database.
I assume that you are checking login credentials.
You can add a timeout to your sessions like so:
define('SESSION_EXPIRE', 3600 * 5); //5 hours
if (!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > SESSION_EXPIRE) {
session_regenerate_id(true); // change session ID for the current session an invalidate old session ID
session_destroy();
session_start();
$_SESSION['CREATED'] = time(); // update creation time
}
I think the best method would be before allowing the user to comment, have PHP read your database and check if the individual has publish permissions. If not return an error.
Another thing you could do, which Facebook does, is have an AJAX call checking a PHP file every few minutes. The PHP file simply returns whether the user is logged on or off and if they are logged off, Javascript redirects them off the page.
Related
I try to destroy the Session from a other user after I changed his permissions or his ban-status...
I write the session key from every user in to the database and catch them if I visits there Profiles. If there are any changes I want that the User will get kicked out of the System instantly...
Here is my code:
FUNCTION back_to_home() {
mysqli_close($db);
$session_id_to_destroy = $_SESSION['visit_user-session_id'];
session_id($session_id_to_destroy);
session_start();
session_destroy();
unset($_SESSION['visit_user-username']);
unset($_SESSION['visit_user-e_mail']);
unset($_SESSION['visit_user-register_date']);
unset($_SESSION['visit_user-last_login_date']);
unset($_SESSION['visit_user-register_ip']);
unset($_SESSION['visit_user-last_login_ip']);
unset($_SESSION['visit_user-steam_id']);
unset($_SESSION['visit_user-permissions']);
header('Location: ../../../');
exit;
}
I hoped I can fix or do that with PHP. I have no clue of JavaScript xD
So what I want to know is, Can I do that like that or is there another way to kick out another user from his session?
I try to destroy the Session from a other user
You can technically do this, yes, but the process is long winded and problematic.
How to delete an arbitary session.
A: Finding the session
You need to use the session_id value. This value is part of the file name (or in the case of database sessions the session identifier column value).
You need to know the file name precursor (usually sess_ but can be anything as set in the PHP source code). You also need to know the session storage location as set in your PHP.ini file.
Example:
A session with id 58ce93c623376b3ddfca3cfc3a01d57d3be85084363147464 is a file at:
/home/session_storage_folder/sess_58ce93c623376b3ddfca3fc3a01d57d3be85084363147464
But session file names are generated on the fly and are not (and should not be) connected to whose who on your membership database.
If you generate session id's manually then this becomes easier, but the security of sessions becomes greatly reduced and this should really, really not be done without very careful thought.
B: Finding the user
Now you need to find the User that you want to ban. The session file will contain the users id, somehow,
Session data is stored typically as:
(Example)
$_SESSION['alpha'] = "UiOvMfV9byatH4Wt1SPYUO3zgsj5";
$_SESSION['beta'] = 1324;
alpha|s:28:"UiOvMfV9byatH4Wt1SPYUO3zgsj5";beta|i:1324;
Which is
[var name]|[var type]:[var contents length]:[contents data]; [etc....]
So if you had a user id value set as $_SESSION['user_id'] = 45; this would be:
user_id|i:45;
In the session. So you would need to search every session you had for this data string.
Please read this question about how to do this
So you would have code like this:
$string = 'user_id|i:".(int)$user_id_to_block;
$session_file_name = null;
foreach (glob('/home/session_folder/*') as $file) {
$content = file_get_contents("/home/session_folder/".$file);
if (strpos($content, $string) !== false) {
$session_file_name = "/home/session_folder/".$file;
}
}
Once found, you can then delete that session on the server.
if(file_exist($session_file_name)){
unlink($session_file_name);
}
BUT:
With many sessions this will be very slow and inefficient.
How you Should be doing it
Each page load you should be checking the logged in user is authenticated. Assuming your user details are database driven, every page load you should be checking that the details are genuine.
<?php
session_start();
if($_SESSON['user_id'] > 0){
/////
$sql = "SELECT banned FROM users WHERE user_id = :user_id";
/////
// Etc. etc.
$result = get MySQL result;
if($result['banned'] === 'Y'){
/***
* Member is banned. kick them out.
***/
$_SESSION = []; // reset session.
header("Location: index.php");
die();
}
}
UPDATE
If you are using the session ID as an identifier and you know the session id without needing to search for it; simply do this:
FUNCTION back_to_home() {
mysqli_close($db);
// save current admin session (optional).
$admin_session = session_id();
// get target id.
$session_id_to_destroy = $_SESSION['visit_user-session_id'];
// close the current session.
session_write_close();
// load the specified target session
session_id($session_id_to_destroy);
// start the target session.
session_start();
// clean all session data in target session.
$_SESSION = [];
// save and close that session.
session_write_close();
// Optional if you need to resume admin session:
// reload admin session id
session_id($admin_session);
// restart admin session. . ..
session_start();
// ...
// header should go to a specific file.
header('Location: ../index.php');
exit;
}
I googled to solve my question but any site explains my problem in a different way so I feel very confused!
I realized a php site in this way.
index.php:
In this page I get username and passw from login form and after checked if the user really exist I'll save them first in a variable and after in session.
$_SESSION['user']=$user;
$_SESSION['psw']=$psw;
Now I would show this page ONLY if the user is logged, so I would make some like this:
first_page.php:
<?
if(isset($_SESSION['user']) && isset($_SESSION['user'])!="" && isset($_SESSION['psw']) && isset($_SESSION['psw'])!=""{
// show page site
}
else
// go to index.php
?>
and insert this block if-else in any pages of the site.
It is correct this procedure?
I need to introduce session_start(); in any page or just in index.php?
How long time $_SESSION['user'] and $_SESSION['psw'] (expires)?
Since the site needs $_SESSION['user'] for many features, I need to be sure that when a user navigate the site those session variables are setted.
Thanks for your support, I feel very confused on it.
You must add session_start() in every single page where you use $_SESSION. It expires when you leave the site.
Don't store a password in a session, without changing the session handler data in a session is stored as plain text outside of the web root. This means anyone that has access to the system can read session data.
The method of knowing if a valid login occured is:
$sql = "select id where username = 'username' and password = 'hashedpassword'"
If an id is returned it means the user successfully logged in and store that ID in a session. Then validate if the session continues if the ID is set.
Keep in mind that after raising privileges it is recommend to change the session id as well, that can be done with session_regenerate_id() this to add protection for session fixation attacks.
At the beginning of each script when trying to read data from a session use session_start() and session_destroy() to remove all data stored in that session (usually a logout)
If I introduce at the top of any page the following script, could be a good solution? Or there's something wrong?
if ((isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) || $_SESSION['iduser']==NULL) {
// last request was more than 30 minutes ago
session_unset();
session_destroy(); // destroy session data in storage
echo "<script>location.href='index.php'</script>"; //redirect the user to index page
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
/* Code for the rest of my page HTML*/
(took from here: How do I expire a PHP session after 30 minutes?)
So I got an ini.php file which I included on top of every file. It includes my database connection + session_start().
When the login of the user is succesful then I set a session which equals $_SESSION['login'] = true.
Now I can do stuff like this:
if (!isset($_SESSION['login'])) {
include 'php/includes/login_form.php';
}
else {
include 'php/includes/welcome.php';
}
What if I wanted this specific login to be specific to the user? Do I have to link the session somehow with the username on login?
A session is always unique to one visitor. session_start generates a random session id, which it puts in a cookie, which only your current visitor will receive. On the next request, that cookie with the unique session id is picked up on by session_start and the session is resumed.
However, this by itself won't tell you which of your user accounts specifically the session belongs to. You'll have to record that information yourself. E.g.:
if (/* login successful */) {
session_start();
$_SESSION['user_id'] = $loggedInUserId;
}
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 am the administrator of the site. I want unset a particular session, and I know its session id.
The users are just starting the session like this:
session_id("usernumber");
session_start();
Let’s say user A has usernumber "123".
I want to destroy all the values of the user A. User A will not regenerate the sessio_id() after setting that as session_id("123");.
How can I unset destroy only for user A?
Answer by Jack Luo on php.net
$session_id_to_destroy = 'nill2if998vhplq9f3pj08vjb1';
// 1. commit session if it's started.
if (session_id()) {
session_commit();
}
// 2. store current session id
session_start();
$current_session_id = session_id();
session_commit();
// 3. hijack then destroy session specified.
session_id($session_id_to_destroy);
session_start();
session_destroy();
session_commit();
// 4. restore current session id. If don't restore it, your current session will refer to the session you just destroyed!
session_id($current_session_id);
session_start();
session_commit();
Without reverse enginering the session handler....
<?php
session_id($_GET['killsid']);
session_start();
session_destroy() || die "failed to kill";
You could try to get session_save_path() (in this directory session files are stored).
When you are using default session names the filename looks like sess_jgimlf5edugvdtlaisumq0ham5 where jgimlf5edugvdtlaisumq0ham5 is user session id so you can just unlink this file unless you dont have permissions to edit those files.
As far as I know, the only supported way to do so with the default session handler is to impersonate the user with session_id("usernumber"); and then remove the values.
You could also store sessions in a database, which would make this all pretty straightforward, yet you need to write your own session handling code.
BTW, the session ID is supposed to be a long random string which you cannot guess. Using 123 means that any anonymous visitor can easily log in with any user credentials.