How to validate user session on every page - php

I'm working on this project in Codeigniter and i created login and register script but I don't know how to validate user on every page.
When user logs in what data to store in session (Ci session user_data), so i can compare it to database on every page to se if the session is valid?
I'm using codeigniter's session class and I'm storing the values automatically in the database. Please help me I'm stuck here...
My session is handled like this :
1. When ever any user reaches my webpage he gets unique hashed (md5) session id that is checked when ever a page is loaded. If it exists do nothing if it doesn't generate a new one. It changes every 5 minutes.
2. When user logs in what data to pass to so i can compare it to the database later on ( on every page load)
I don't know if storing only the 'is_logged' = 1 cookie is safe. I want to check cookies on every server request.

Upon succesful login, you create a
$this->session->set_userdata(array('authorized' => true));
You can then make an auth library, or a model method, whatever suits you that just checks if this session data exists.
function is_logged()
{
return (bool)$this->session->userdata('authorized');
}
if FALSE, user is not logged, if TRUE it is. You can call this function on every controller's method you need to place behind authentication, or in controllr's constructor if you need it for all methods (ex. an admin panel)
have a look, for ex., on how Ion Auth, one of the mainstream Auth Libraries in CI, handles the thing (uses the logged_in() method which does the same as in my example code. Keep in mind that sessions are encrypted, and if stored in database security is even higher);
https://github.com/benedmunds/CodeIgniter-Ion-Auth/blob/2/libraries/Ion_auth.php

Sessions are stored on the server so no validation is required. You only need to validate what you put in the session.
Sessions are authenticated by the user supplying a session_id cookie (PHPSESSID).
Cookies on the other do require validation, but cookies shouldn't be used to store critical data so it's a bit moot.

You should have write a function in helper like session_helper.And in constructor of your class call this helper method.If your user is logged in correctly then it will continue,other wise it will redirect to log in page.Your Helper should be like this
function session_set()
{
$ch=&get_instance();
if($ch->session->userdata('your_session_id')=='')
{
redirect('your_login_page');
}
and in controller you should check like this(constructor)
session_set();
Hope this will work for you

Related

Check/Validate and reuse CodeIgniter session

I have a website for my website with 20 api calls (REST). for every call the user/pass input is required.
The API calls can be made from C++, Python, PHP, Java, ASP etc...
the issue I have now is it creates tons of sessions. I want to change this to allow all calls to re-use the session id assigned.
so the first call will be to "authenticate", this return a token (encrypted session id)
then I decrypt this token and check if the session id exists in the database. If it does, i want to load or assign this session
I found a pge from ellislab explaining session but it does not help me since this page creates new session.
example:
call #1: authenticate(user,password)
call #2: get_report(token, 1) // get report id 1
call #3: add_user(token, [array of user data])
How can i reuse the session in codeigniter?
You just need to save the token in session if not exist.
1) Get the token form your request like username I think user name is unique for you.
2)
$this->load->library('session');
$user_data = $this->session->userdata('$username');
if(!empty($user_data)){
//use the same session
}else{
$this->session->set_userdata('$username', 'isvalid');
}

Should I check for user authorization in every page and request?

I created a system that uses username/password login system with with 'phpass' class to store hashes and check passwords when user logs in.
I also use AJAX to load user information (that can only be retrieved if user is logged) with javascript.
My question is, should I check for user's authentication in every page and in every file that returns AJAX values or just create a 'connection' entry in MySQL database.
Is it wrong to use 'phpass' functions in every page and request because of performance or is it wrong to use the database method?
What's the best method to keep user connected and check in every page if the user is logged?
Use a $_SESSION and check it on every page
i.e.
$loggedIn = ($_SESSION['logged_in']) ? TRUE : FALSE;
if($loggedIn == TRUE){
//Do stuff here for a logged in user...}`
If you include some config file in header or some other file, which is available on whole website then check in that file for logged in session, rather adding code to every page

Best way to save object's data in php?

I am trying to create a log in system in php. I have 3 files. index.php, login.class.php (defines Login class), securePage.php.
Login class has different functions such as getUserName(), addUser(), etc.
index.php creates a new $login object, has a log in form and create a new account form.
When you create an account on the index.php page,
$login->addUser($username, $password, $first_name, $last_name, $email); function executes which creates a new account.
After you log in and hit submit, the script checks your username/password/etc and redirects you to securePage.php.
After I redirect to securePage.php from the login.class.php, I am not sure what's the best way to check if the user has logged in correctly and have all the user's information handy.
Right now my securePage.php creates a new login object
$login = new Login; and checks if the user has access to the page by calling checkAccess within the Login class.
// Check if the user has access to this page, otherwise redirect to login page
if($login->checkAccess()) {
//blah blah blah
}
This is how checkAccess function looks inside Login Class
public function checkAccess() {
// check the session access
if(isset($_SESSION['username']) ) {
//
return true;
}
}
I feel this is bad implementation because
a) I create a brand new login object and lose my data
b) I only check if the session is secure by checking if session's username is set which can be probably faked.
What's the best way to implement securePage.php in terms of still having all the user data and checking if the user is logged in?
Session data is server side data -- it can only be faked through manually guessing PHPSESSIONID (You can read up on that here).
The way that this is normally handled is one of two ways. If HTTP Authentication is being used (which has some major benefits, BTW), then basically every time a secure transaction needs to occur, the UN/PW have to be tested. On the other hand, if the server is storing the value (say in $_SESSION or some other framework equivalent), then the server already has the data and there is no point in re-querying.
If you have implemented the methods __sleep and __wakeup properly, you can simply store the entire login object in $_SESSION, which would generally be my preference.
Your session is stored server side, and thus is a good way to check for a login status. There are some issues like f.e. account sharing but they shouldn't be a problem for the application you are developing.
I wouldn't be checking on the username though, I'd add a key called 'authorised' or something. also I'd call the function isAuthorised instead of checkAccess, as checkAccess would indicate using user roles/rights to me.

Update another user's session - best practice?

As in many web applications, when my users log into my site, I set several session variables that control permissions for accessing site functionality.
Whenever a user undertakes an action that would result in a change to those permissions, I update the session variables as part of the normal processing flow.
But sometimes a user's session needs to be updated based on the actions of another user. For example, a moderator upgrades a user's permissions. The moderator does not have access to the user's session space, so the normal update functions cannot be run for the affected user.
I have considered a few ways of forcing an update to another user's session, but they all have drawbacks:
I could search for and delete their
session from the sessions table, but
this requires a full table scan
(where sessdata like '%user_id%'),
and it could cause the loss of
content that the affected user may be
engaged in generating.
I could force a session update
periodically, such as when
sess_time_to_update is triggered.
But there is no guarantee that this
will transpire prior to the user
attempting to access the
functionality for which the update is
needed.
I could run a complete series of
variable updates on every page load,
but the whole point of maintaining a
session is to avoid that overhead.
I could set a flag indicating the need
for a session update, but that signal
would have to be interrogated at every page execution, and in every controller. (I know that I could extend CI_Controller as MY_Controller, but I don't want to do that)
I'm already sending the user an email
notifying them of the change in
permission, and it's easy enough to
make them click a session update link
(or even log out and log back in).
But there's no guarantee they are
going to even read beyond the subject
line, let alone actually click the
link.
So is there anything I'm missing? Am I looking for a magic bullet that does not exist?
(Note that I've tagged this with CodeIgniter, and made reference to CI-specific technical details, because that's what I'm using. That said, this isn't a CI-specific (or even a PHP-specific) issue.)
Thanks for the help!
Well, one option would be to set an "ACL Version" number (either for all users, or for each user). Then when initializing the session (well, when you call session_start()) check to see if the stored version matches the session's version. If it doesn't, refresh the ACL.
Another slightly different way would be to add a column to the sessions table ("status" or "dirty", etc). Then, instead of killing the session, simply update that status to 1. Then when loading the session, check that flag to see if it's 1. If so, reload the cached data in the session and set it to 0. If not, continue on...
As far as updating another user's session, I wouldn't do that... If sessions are managed by PHP, then you'll need to kill the current session and start the one you want to modify. That's just asking for problems... (you need to do that, since PHP's mechanism does not use serialize.).
As far as deleting their session, I wouldn't worry about the full table scan. Unless you have a TON of users updating permissions all the time, it's not going to matter. The data loss is a significant concern, so that nicks that idea...
As far as the other 2 options, I think you hit the nail on the head, so I have nothing else to offer on them...
I'm going to take a stab, though my approach is not entirely applicable to Code Igniter.
The way I've solved this problem in the past is to make a User object model with a constructor that takes the UserID from the database primary key where the credentials are stored. I'll write a static login method that checks login credentials and then instantiates and returns an instance of user if the login is correct for a row and then sets the session.
So far so good, right? So all your permissions, access levels etc are stored in the database. Just like having a login method, we can have a refresh method that reinstantiates the object, re-fetching from the db off the already obtained primary key.
class User{
public function __construct($uid){
//fetch from the db here
$sql = 'SELECT FROM User_Table WHERE UserID = ?';
$params = array($uid);
//fetch and assign using your flavor of database access, I use PDO
//set all your object properties for access, as well as user_id, something like
//$this->user_id = $result['UserID'];
}
public static function Login($uname, $pass){
$sql = 'SELECT UserID FROM User WHERE Username = ? AND Password = ?';
$params = array($uname, md5($pass));
//again I'm going to employ pseudocode here, fetch according to your preferred system
if(!empty($result)){
$_SESSION['user'] = new User($result['UserID']);
}else{
//login failed!
return false;
}
}
final public function _refresh(){
//refresher method. Since the controller sets all the object properties for access
//reconstructing and assigning it refreshes these priveliges.
$_SESSION['user'] = new User($this->user_id);
}
}
Using this model, whenever I am performing an action with the user in the session that might potentially need time-sensitive permissions, I can call refresh on the user object all ready in the session. Let's say we have a controller function to access a restricted form.
function _topSecret(){
$_SESSION['user']->refresh();
if($_SESSION['user']->specific_permission_from_db){
//Perform the special action, get the view, whatever.
}else{
//redirect to an error page
}
}
So if you already have routines written for the admins, all they need to do is set the user's privileges in the database, and when the refresh method runs on the specific, time-sensitive functions, that data will be put in the session for the user. So you're not necessarily updating another user's session, you're just determining which actions are so chronologically sensitive they require the newest permissions and issuing that command to the user object in the session.
This has proven pretty efficient for me, since reconstructing need only be performed on actions that need the most up to date permissions. Again, I'm not sure how useful it may be in the context of CI and your individual application, but I figured I'd share. I'm assuming you've already done all the necessary session security measures and started the session - most frameworks like CI will handle this for you through their native means.
Add a column in the session table that can hold the primary key of the user object. Set it upon login and use it later to update the session.
Edit: If you don't want to extend the session table, make an additional lookup table where you have the user object id and the session key link.
If your're storing the session as a native php session I'd tend to leave it alone, and allow them to get some kind of notice that they need to login/out to refresh the setting. I've also had sites where the session data is stored in the db and then its much more trivial to just write the new setting in.

Dividing lines between Session Object, User Object, and Login Controller

I'm developing my own PHP framework, and I'm trying to do things more "by the book".
I want to build login system. I have done this plenty of times, but now I just want to confirm/get some feedback on a system.
I know we need...
A Session Object
A User Object
A Login Controller
What my question is, is who holds what power?
Here's my thought - when you submit your un/pw, it obviously goes to the Login Controller. We need to look up that un/pw combo in the user database, and therefore I feel as if that should be done in the in the user object ... $User->authenticate($un, $pw).
All that should do i return true or false. Then the LoginController should tell the Session object to create a session ... $session->create(). But apart of me wonders if the User and Session object should be a bit closer knit, and not rely on a Controller.
Looking for opinions, thanks in advance.
In my opinion, the user object shouldn't know about persistence (session) or the application (controllers). All it should care for is representing a user and handling user-related functions like authenticate.
The controller is all about application logic, and the session is part of the application. I feel like it's the controllers task to open the session and store the user object for later usage, once authenticated.
P.s. Did you publish your framework? Github it! :-D
My thoughts for a framework like this:
Initialize session object on page loads, and set it to default to a "guest account".
Upon this initialization make your session object to look for a session identifier (from a cookie?) and validate that ID against your session tracking back-end, be it database or whatever you are using.
If the session ID validates, you get your relevant user ID which you can then use to populate the user object.
Login control should just authenticate the user from login, and initialize the session by binding session ID and user ID on the back end, and by writing the session ID to a cookie.
... A more efficient way, however, would be to authenticate the user once and write the user ID to a digitally signed cookie set by the server, and trust all valid cookies returned by the client. This would make session management so much lighter and save round trips do database.

Categories