PHP $_SESSION for multiple users at once - php

I'm wondering about how the $_SESSION array works. If I have a lot of users using my site do I need to set a subarray for each user? For instance right now I have
$_SESSION['userid'] = $userid;
$_SESSION['sessionid'] = $sessionid;
$_SESSION['ipaddress'] = $ipaddress;
but in order to cope with more users do I need to make a multidimensional array?
$_SESSION[$userid]['sessionid'] = $sessionid;
$_SESSION[$userid]['ipaddress'] = $ipaddress;
Is the $_SESSION global handled per client or just overall? Will having $_SESSION['userid'] set on login kick the previous user out and instate the latest logged in user?

No. There is a seperate $_SESSION created for each user. This is all done by the server, you don't have to worry about it. When writing your code, treat the $_SESSION as if there was only one user on the site.
Edit: Actually, on thinking about it, it is a very good question to ask. It is good to ask these sorts of questions, it means you are seriously thinking about how your code truly works. Keep asking these things, and keep testing. I have a feeling that one day you will be writing some amazing code.
So on that note, here is some info from the apache site:
What is a session?
At the core of the session interface is a table of key and value pairs that are made accessible across browser requests. These pairs can be set to any valid string, as needed by the application making use of the session.
Keeping sessions on the server
Apache can be configured to keep track of per user sessions stored on a particular server or group of servers. This functionality is similar to the sessions available in typical application servers.
If configured, sessions are tracked through the use of a session ID that is stored inside a cookie, or extracted from the parameters embedded within the URL query string, as found in a typical GET request.
And from the PHP docs on Sessions:
Session support in PHP consists of a way to preserve certain data across subsequent accesses. This enables you to build more customized applications and increase the appeal of your web site.
A visitor accessing your web site is assigned a unique id, the so-called session id. This is either stored in a cookie on the user side or is propagated in the URL.
The session support allows you to store data between requests in the $_SESSION superglobal array. When a visitor accesses your site, PHP will check automatically (if session.auto_start is set to 1) or on your request (explicitly through session_start() or implicitly through session_register()) whether a specific session id has been sent with the request. If this is the case, the prior saved environment is recreated.

well after searching alot and working on session i found my own way. i hope it works great for everyone here
this is the query for login page for my users:
here i am storing email as session from input field after matching data from mysql
<?php
include_once("dbcon.php");
$que=mysqli_query($con,"select * from agents where companyemail='$email' AND
pass='$password' AND post != 'Owner'");
$record = mysqli_fetch_assoc($que);
$_SESSION[$email]=$email;
header("Location:/dashboard/woresk/Dashboard_For_Agents/light/index.php?
&loginid=$agentid");
?>
and then in the dashboard for users there is a logout option where i used this method
<?php
session_start();
include_once("dbcon.php");
$sid=$_GET['loginid'];
$que=mysqli_query($con,"select * from agents where id='$sid'");
$recorde = mysqli_fetch_assoc($que);
$email=$recorde['companyemail'];
unset($_SESSION[$email]);
header('location:/dashboard/woresk/index.php');
?>
and to avoid users to enter dashbboard if they are not login or thier session is not set following code works great for me
<?php
session_start();
include_once("dbcon.php");
$sid=$_GET['loginid'];
$que=mysqli_query($con,"select * from agents where id='$sid'");
$recorde = mysqli_fetch_assoc($que);
$email=$recorde['companyemail'];
if(isset($_SESSION[$email]) && isset($_SESSION['alllogout'])){
}
else if(!isset($_SESSION[$email])){
echo
"<script>
window.location.href='/dashboard/woresk/index.php'
</script>";
}
else if (!isset($_SESSION['alllogout'])){
echo
"<script>
window.location.href='/dashboard/woresk/index.php'
</script>";
}
?>
i hope this works for others too. if any question please let me know

Related

Login, user authentication, session and csrf tokens [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I started learning PHP about a month and a half ago, and I started doing so by trying to create my own very simple CMS in order to learn how to construct basic CRUD scripts that would interact with a mysql database and so on.
I am currently building my login form for the private admin section of my CMS and by doing so I wanted to learn about basic security in PHP.
I wanted to do some basic research on user authentication but the explanations I came across often included information on best security practices which I did not fully understand.
So, I looked for more information on the small bits I did not understand which included other bits I was not acquainted with and I got dragged into absorbing a lot of information on security topics like security through obscurity, one way password hashing, security through proper php configuration setup, defending against sql injection, php injection, session hijacking and so on.
I am having trouble implementing all this since I can't really make sense of it all.
So the first question is about storing the user session in the database.
What I know at this moment is that if I am using a shared host, the server might not be configured properly and the folder where the server is storing the session might be accessed by other people.
Is this the only reason why I would like to store the session in the database?
Second, how does storing the session in the db solve the access problem?
To elaborate on my confusion, it is clear to me that once the session is stored in the database it safe from the people on the shared host, but how do I tell php -"Hey, I stored my user session in the database, exclude it from wherever you are instructed to store it by default"?
In other words, just because I stored the session in the database does not mean that the server excluded it from the place where it stores the sessions by default. Is this correct, and if it is how do I take control over that?
Third, how do I actually store the session in the database? I assume the following process:
session_start();
//Assume a user has successfully logged in
//For better security regenerate the session on login
$session = session_regenerate_id();
$data[]= $session;
$query = $db_connection->prepare("INSERT INTO `sessions`(`session`) VALUES (?)");
$query->execute($data);
Is this what it means to store the session in the database in its most basic form?
Moving on to the next question.
Lets assume that I have resolved the issue above. Now how do I authenticate if a user is logged in?
Normally I would do something like this:
if(!isset($_SESSION['user'])) {
redirect_to('login.php');
}
But since the user session is stored in the database, is it available to me directly or do I need to pull it out of the db first in order to use it?
I am aware of the fact that once a session starts there is an encrypted/hashed (don't know exactly which one it is)session cookie in the browser called PHPSESSID.
But since I am storing the session in the database to me it means I am taking manual control of what PHP usually does automatically, which in my head the process chain is generate->store->encrypt/hash->set session cookie.
Is that assumption correct?
And lastly cross site forgery requests.
My understanding is that while a user is logged in, he is tricked somehow to click on a link, etc. that will copy his browser's cookies and now the attacker is in possession of the session cookie and can impersonate the user.
How does a csrf token stored in a hidden field on my forms help in this situation?
If the attacker has hijacked the session of the user checking the token against the session does not help since the attacker has a valid session.
What am I missing?
There are knowledge gaps in my head on how things work, I hope you can somewhat fill these for me.
Is this the only reason why I would like to store the session in the
database?
The database is password protected, the sessions directory isn't. This goes without saying that most servers should secure the /tmp/session path (iirc) and nobody can access it.. but again, you'd have to trust the host quite a bit.
Second, how does storing the session in the db solve the access problem?
See answer #1
In other words, just because I stored the session in the database does not mean that the server excluded it from the place where it stores the sessions by default. Is this correct, and if it is how do I take control over that?
Basically, sessions are identified with a unique IDentifier. The browser is sent a cookie with the ID, and the server reads the cookie ID and references it to a configured location on the server. To set the save path, you can use session_set_save_handler - this will allow you to do whatever you want with the session (on save) - such as save it to a DB. See Example #2.
Now how do I authenticate if a user is logged in?
**There are various ways to determine if a user is logged in. A basic way is to store unique data in a session and relate it to the users table. When the browser sends the session ID, the server can then retrieve the data based on the ID. You can then take this data and cross-reference it with your users table to authenticate the user. Remember, servers are (typically) stateless, meaning navigating between pages, the server doesn't keep track of users between pages. Hence the use of sessions. A very basic example, and I wouldn't use this, is such:
<?php
function isLoggedIn() {
if(!empty($_SESSION['user'])) {
$uuid = $_SESSION['user']['uuid']; // universal unique id
$username = $_SESSION['user']['username']; // username
$last = $_SESSION['user']['last']; // last use of session
if($last > time() - 600) { // active last 10 minutes?
$stmt = $db->prepare("SELECT username FROM users WHERE uuid = :uuid");
$stmt->bindValue(":uuid", $uuid, PDO::PARAM_STR);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if($username == $user['username']) { // user is logged in. uuid on session matches uuid in users table
$_SESSION['user']['last'] = time();
return true;
}
}
}
session_destroy(); // clear everything!
return false;
}
?>
But since the user session is stored in the database, is it available to me directly or do I need to pull it out of the db first in order to use it?
Don't confuse user session with the user object itself. The session is used to tie the actual USER and the APP together. See above answers & example
How does a csrf token stored in a hidden field on my forms help in this situation?
When you have CSRF tokens in your forms, you also have the CSRF token on the server... Meaning when the page with the form is loaded, a CSRF token is generated and stored in a session for the specific user. Remember, users who have session cookies do NOT have data -- just identifiers. The form will also have a hidden field, such as csrf_token. On POST, the server will compare the post token with the session. It will ALSO reset/clear the token so that it cannot ever be posted/used again. These tokens should be unique.. usually something like md5(time()) works well. If the token doesn't match, or is missing, it's possible there's an attack. The best action to take here is to display the form again, with a new CSRF token.

How to add security while using GET and POST method?

I developed a small application Contact Manager and while updating the contacts, the contact id is being sent using GET method. But a user can change the Id and edit any contact, how can i add security to it?
<td>
Update
</td>
http://localhost/contmanager/home.php?action=update&contactid=1
If i change the id to some other number, another contact will show up.
You can't control what the client asks the server to do.
If you want to add restrictions on who can modify particular contacts then you need to Authenticate (username + password, client SSL cert, OpenID, etc) users and then check if they are Authorized (this will depend on the business logic you decide on) to modify the entry in question.
As Quentin pointed out, your logic is going wrong here, data like these should be stored inside sessions and shouldn't be passed using $_GET or $_POST, unless and until required, if you still need to pass for some reason, than you can read my answer ahead for a solution.
Store the user id in a session, so when the user updates, just compare the session id and $_GET id, if it matches, update the entry else throw an error.
When the user logs in
$_SESSION['user_id'] = $db_data['col_name'];
Now, before the entry is updated...
if(!empty($_GET['user_id'])) {
//First validate, you can check whether the id is only numeric, is valid db entry etc
$user_id = $_GET['user_id']; //Store the id in a variable
} else {
//Invalid
}
if($_SESSION['user_id'] == $user_id) { //Compare the ids
//Process
} else {
//Not Valid
}
Note: Make sure you use session_start() at the very top of the page,
before you start writing anything.
You need to use session and to store the data inside like this:
<?php
session_start();
$_SESSION['contact_id']=$contact->contact_id;
<td>Update</td>
?>
use it like this:
http://localhost/contmanager/home.php?action=update
and when you need to use contact_id(after the GET) :
session_start();
if(isset($_SESSION['contact_id']) && !empty($_SESSION['contact_id'])){
$contact_id=$_SESSION['contact_id'];
}
A PHP session variable is used to store information about, or change settings for a user session. Session variables hold information about one single user, and are available to all pages in one application.
PHP Session Variables
When you are working with an application, you open it, do some changes and then you close it. This is much like a Session. The computer knows who you are. It knows when you start the application and when you end. But on the internet there is one problem: the web server does not know who you are and what you do because the HTTP address doesn't maintain state.
A PHP session solves this problem by allowing you to store user information on the server for later use (i.e. username, shopping items, etc). However, session information is temporary and will be deleted after the user has left the website. If you need a permanent storage you may want to store the data in a database.
Sessions work by creating a unique id (UID) for each visitor and store variables based on this UID. The UID is either stored in a cookie or is propagated in the URL.

Proper security for communication with DB in Web App

I really have a lot of questions about this specific area. But basically I just want to know how to create the most efficient and secure php session communication method. I have read so many websites talking about this and they don't seem to agree or relate to my current situation.
My problem is that I don't know how to create login, sessions, cookies, registration etc. properly to match a high security level. This is my idea so far.
1. PHP SESSIONS
I will start a session after the login has been made. I know that there are different ways for me to handle these but at the moment I have created a session variable like so $_SESSION['user'] which lets me store the users e-mail address during the session. Then I have a problem when the session is ended with the server. That leads me to the next property.
2. COOKIES
With cookies I would be able to store the e-mail address and the hash encoded password and then be able to recreate a session based on these login information.
<?
session_start();
require_once('config.php'); //retrieved from the servers include folder specified on the apache server.
// if session is closed that means that there wouldn't be stored a session variable called 'user' anymore.
if ($_SESSION['user'] == '') {
// if the cookie hasn't been set..
if ($_COOKIE['user'] == '') {
// ... close the session and return to the login page
session_destroy();
header('Location: login.php?err=4'); // err=4 means session ended
} else {
// We don't know wether the user has logged in using e-mail or username, so that's why we connect using either email or username.
$sql = 'SELECT * FROM login WHERE (email = :user and password = :psw) or (username = :user and password = :pass)';
$statement = $conn->prepare($sql);
$statement->bindParam(':user', $_COOKIE['user'], PDO::PARAM_STR);
$statement->bindParam(':psw', $_COOKIE['psw'], PDO::PARAM_STR);
if ($statement->execute() && $row = $statement->fetch()) {
$_SESSION['user'] = $_COOKIE['user'];
} else {
// Failed to retrieve data somehow.
}
}
}
?>
But then I have read that the session_id() also is a cookie stored value, which will be the same every time I recreate the session. So I actually don't have to match the values to the server again, cause I can simply start session again and continue from where I left.. But I see this as a security break, since that if the session_id() has been retrieved by somebody else, they will be able to connect using same session_id() etc.
3. I also need to use the values from other domains
I know that it is possible to use the same login-details from another website e.g. Facebook, Google etc. I want to be able to reuse the same login for all the domains I am working with, but how do I secure that only mine (registered) domains can have access to the login information, and not other sites?
4. Is there another secure way?
This is actually my question. I am not sure that what I have done or planned is highly secure, and I definitely don't think that my newbie experience is good enough to create a login-secure database connection. So I would like to know if anybody could link me to the official page of the right way to store and use login details in PHP in the most efficient and secure manner.
PHP sessions are the way-to-go when you want to handle logins in PHP. To do this in a save manner you should make sure that your session data is stored on your server and the client only has a session_id in a cookie.
Every time you have a security-level change (login, logout etc), you should regenerate the session id to ensure more safety (old stolen session id's will become unusable). You should also make the session cookie http_only, which will make it impossible to steal the cookie using JavaScript.
From a security perspective I would recommend you to never use cookies to store sensitive information. Information stored in cookies are not save, they are stored on the clients computer and can be altered or stolen.
Google and Facebook make logging in to all kinds of websites possible using openAuth(2). I'm not sure whether that would be usable for you, but cookies will only be accessible by at most one domain.
I would recommend using PHP sessions, they are secure if you handle them correctly. If you are not really sure how to do that you could take a look at some good PHP frameworks. I know from experience that the Laravel framework has a good login-handler.
Sessions already use cookies to keep the session. If you configure it properly, you can keep sessions open indefinitely, if that's what you want to do (unless the user deletes cookies, but then your cookie-based solution won't help either). Anything you build yourself with cookies will probably be less secure than that, so I wouldn't bother with it. Properly configure the session settings of course.
Reusing information across domains is a complex field. If they are all backed by the same database, just let the user log in on any site. You will need to manage separate sessions (read: user will need to log into each site separately, but can use the same user/password) or built some pretty complex cross-domain session sharing (hint: you probably don't want to). If you want to go for a more complex solution (e.g. because your domains don't share a central database), google "single-sign on" and prepare for hours, days and weeks of reading.

PHP: User logged in sessions and cookies

Sorry for the newbie question! I'm making a small website that allows users to create their own accounts. It's not a banking system, and it's unlikely that someone would want to hack it. That said, I am trying to make it reasonably secure, as there are plenty of bored script kiddies out there.
Could someone describe a basic workflow for a user logging in and having a cookie set that will keep them logged in for 30 days?
At the moment I have the following:
Validate and sanitize inputted data.
Check supplied credentials against bcrypt hashed password in DB.
If correct then call "Login" function.
Login function:
a. Delete any session data from DB with userID (table with two columns: SessionString and UserID).
b. Add new session data to DB (newy random generated string and UserID).
c. Write random generated string and UserID to cookie.
d. Set $_SESSION("UserID") with $userID.
But although the two cookies are being created and written to, the $_SESSION("UserID") remains blank... I'm guessing because I can't write to $_SESSION any time I like?
And even once that's fixed, how do I use the data stored in the cookie to log a user in? I'm guessing I don't want to go to the DB on every page load. And it will still require me to create a database object to see if the credentials in the cookie are ok. Is this the right way to this?
Once again, apologies for the newbie question!
UPDATE:
Yes, I do understand the difference between $_SESSION variables and a cookies. I also have session_start() at the top of every page (right after <php with no blank lines). $_SESSION("UserID") just remains blank.
Here's the code from the top of the page:
<?php
session_start();
if(!isset($_SESSION['initiated'])) {
session_regenerate_id();
$_SESSION['initiated'] = true;
}
Thanks for the help.
First off, there is an important difference between a session and a cookie. When you use the $_SESSION[".."] you are creating a session (which lives on the server, compared to a cookie which lives on the client), even though the browser uses a cookie to keep track of the session id. To create a cookie you would use the setcookie() method.
That said, I would recommend you to read through this article which is a step-by-step guide on how to create a secure login script, with persistence using a cookie for a "Remember me"-feature. Describe how to do it in detail would be to extensive for an SO answer im afraid.
Side note:
To be able to write to the session, you might have to call session_start(); prior to getting or setting a session variable using $_SESSION[".."].
Did you write a custom session handler that has your session-files stored in the db? I guess you don't.
If you want to use $_SESSION you have to also do session_start(). When using PHP sessions the cookie to identify the user will be set for you. You will also get session files created in your /tmp directory. That's the location your variables and anything you assign to $_SESSION will be stored.
Unless you define a custom session handler, that will manage the location of the session files, you won't need to query your database. Just save the users credentials in $_SESSION.
See this Tutorial on how to use PHP sessions.
PS: You access arrays like this: $_SESSION["UserID"], not with ().
you might want want to look at this article in which i have already discussed about various types of session hijacking and how you could avoid it.
session security in php

PHP login user logic

I've scrapped all the tutorials that have never worked for one reason or another, and decided to roll out my own registration/login feature on my own, and to my surprise it actually works!
But what I don't get is how the logic behind keeping somebody logged in works! Like, once they've logged in, do I just $_POST their data to whatever other page they visit and once they're on the new page $_REQUEST that post data from the URL and display a message like: "yeah, you're still logged in"?
I'm a bit confused atm, so I hope this question doesn't confuse you too.
Let us have we have pages like login.php after_login_page1.php after_login_page2.php
You can follow these simple steps
Set $_SESSION['id'] = $userid //userid from db in login.php
always have session_start() in the successive pages like after_login_page1.php, after_login_page2.php
Check if(! isset($_SESSION['id'])){
header("Location: login.php");
}
at the logout.php page give $_SESSION['id']=''; and do a session_destroy()
The easiest imo is to use a session.
Basically this is PHP automatically setting a cookie (or adding a piece to the url, depending your configuration) on the user system and automatically loading it on each pageview. You can then add data to the session and as long as the cookie didn't expire (or was deleted) and/or you don't destroy the session, you will have that data at your disposal on each pageview the user does.
Take a look here for a small intro to sessions: http://www.htmlgoodies.com/beyond/php/article.php/3472581/PHP-Tutorial-Sessions.htm
Once they have logged in you generally have two options. Store their details or an authentication token (something that will help the PHP on the server know who is who) in a session or store it in a cookie. Both have their perks, but you will need to choose the one that works for you.
If you store data in a session, the user cannot access what you have stored, only your code can. This is helpful if you want to store say, their id or username. You can trust that it would always be their id and username, because they cannot modify it.
With cookies, the user can access and modify them because they are stored on their local machines. Because of this, you need to be a bit more sneaky and hash the users details, then verify who it is with some server-side logic. It's a little more complex.
A session implementation might look like this:
session_start(); //Make sure you call this at the top of EVERY page
if($passwordsMatch){
$_SESSION['user'] = $_POST['username'];
}
//Now we have access to $_SESSION['user'] on every page.
On another unrelated page:
session_start();
print "Welcome, ".$_SESSION['user'];
Easiest way is to "keep users logged in" is to use PHP sessions. When you run session_start();, PHP sets cookie with SESSION_ID in users browser so it can identify this user. After that, you can set any data in $_SESSION array which will be saved in session between page requests.

Categories