Viewed   131 times

I'm trying to implement a user policy whereby only one user can login at a time. I'm trying to build this on top of Laravel's Auth driver.

I've thought of using the Session driver to store the sessions in the database and make the keys constant for each username. This is probably a terrible implementation because of session fixation.

What would the implementation be like? What methods in the Auth driver should I be editing? Where would the common session key be stored?

 Answers

3

I recently did this.

My solution was to set the session value when a user logs in. Then I had a small class checking if the session ID stored is the same as the current user who is logged in.

If the user logs in from somewhere else the session ID in the DB will update and the "older" user will be logged out.

I didn't alter the Auth driver or anything, just put it on top when the user logs in. Below happens when login is successful:

$user->last_session = session_id();
$user->save();

To check if the session is valid I used below

if(session_id() != Auth::user()->last_session){
   Auth::logout();
   return true;
}

As you can see I added a column in the users table called last_session

Saturday, September 3, 2022
3

Short answer: YOU CAN'T

The session can be destroyed when the entire browser is closed by simply setting expire_on_close in config/session.php (also make sure you clear the cookies in your browser for this to work):

'expire_on_close' => true,

But there is no way to detect when only a tab is closed in the browser. The closest thing you would have is the JavasSript method onbeforeunload that triggers when you close a tab. But it also triggers when you navigate away from a page or hit the back button, and there's no way to differentiate between those actions.


You could set a very short session time on the server, and "ping" the server from any open page, to let it know to keep the session still in use, which would mean it would very quickly expire when the tabs that have the app open are closed, but that's an extremely ugly solution.

Wednesday, October 26, 2022
4

I read two questions here. The first question, 'What is the best practice to determine if a user is logged in?" and the second question 'Is there a concern of Session-Hjacking and Session-Fixation?'

First question: Most web apps/cms I have worked with have a user object. There is nothing particular special about this object from a code perspective, its just an object representing the user. The currently logged in user has their user object stored in the session. $_SESSION['user']

In Drupal (and other platforms) the a function is used to return the currently logged in user, or False if the user is not logged in.

Example:

function user(){
 if( isset($_SESSION['user') and 
     is_object($_SESSION['user'] and 
     get_class($_SESSION['user']=='myUserClass')) ){

         return $_SESSION['user'];

     }else{
         return False;
      }
}

So in your example we see if ( user() ) { CODE } works because all object evaluate as True in an if clause.

Second Question: Session-Hjacking and Session-Fixation are not really concerns here. The client (a web browser) does not have access to the server's $_SESSION array. So in short, yes you are mixing things up here.

Sunday, November 6, 2022
 
steveha
 
4

You can override the unauthenticated() method in your app/Exceptions/Handler.php file to add the missing route parameter.

use IlluminateAuthAuthenticationException;

class Handler extends ExceptionHandler
{
    protected function unauthenticated($request, AuthenticationException $exception)
    {
        return $request->expectsJson()
            ? response()->json(['message' => $exception->getMessage()], 401)
            : redirect()->guest(route('login', ['account' => $request->route('account')]));
    }
}
Friday, October 14, 2022
5

Laravel uses storage drivers for it's session management - meaning trying to access it's contents through the PHP $_SESSION variable will never work. Your config is setting the default session driver to "native" which (I think) the file session driver, meaning all session data is stored in app/storage/sessions (I believe that it stores the session data in some JSON like structure). You can read more about the session drivers here.

So to answer your question, there are a couple of ways that come to mind to solve this. What I would probably do is implement a simple custom session interface that will simply check if a user is logged in. You can set the user's session to logged in when you authenticate the user through your laravel form. For example:

if (Auth::attempt(array('email' => $email, 'password' => $password))) {
    // Set your user's session to logged in here. You will have to implement some 
    // system to do so, the below code is INSECURE/NOT USEABLE
    $_SESSION['user'] = $email;
}

And then you would do the reverse when the user logs out. As mentioned above, simply setting the user's session to logged in is very insecure for a multitude of reasons, the most glaring being session hijacking. (This is an excellent read on the subject) If you can implement a secure session management system (and really, it should not be difficult and will be lightweight) then I think that this strategy is your best bet.

The alternative is to try to use cookies as the session driver but doing so will add more layers of complexity and garbage as you will first have to get the Laravel session id from one cookie and use that to read another ... not an elegant solution.

So I would recommend using the first method I talked about and implementing a simple and secure session management system. Hope this helped!

Monday, October 3, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :