laravel-auth-token icon indicating copy to clipboard operation
laravel-auth-token copied to clipboard

Alternative strategy

Open malhal opened this issue 8 years ago • 3 comments

Since all this package does is put a token in a database, which then raises all kinds of issues like users not being able to login on 2 devices and tokens not expiring, it suddenly struck me that Laravel already has built-in auth token - it's the session ID. So After you log in why not just send back the session ID in the JSON response. And then include it on the next request as a URL param. Then to log the user you simply load up the other session and get the user ID and then set the current user to the same one:

$sessionID = '4842e441673747d0ce8b809fc5d1d06883fde3af'; // get this from \Session::getId(); from your previous authenticated request (after logging in because it changes).

    $s = new \Illuminate\Session\Store(NULL, \Session::getHandler(), $sessionID);
    $s->start();
    $userID = $s->get('login_82e5d2c56bdd0811318f0cf078b78bfc');

    \Session::set('login_82e5d2c56bdd0811318f0cf078b78bfc', $userID);
    return \Auth::user();

I'm not fully aware of all the consequences of this but there are some great benefits. You get multi-device login, and session timeout. If using cookies then the session that the user is set on, is now authenticated, so it doesn't need to do the steps above again, and as long as its being used it won't timeout, or you could just set the session config lifetime param in session.php to int max. I realised this after hours fighting trying to turn cookies off, so with all this you can just leave them on and not worry about them.

malhal avatar Aug 08 '15 01:08 malhal

Interesting idea, though Im not sure what the security implications would be of using the session like this. The sessions ID's might not be generated with enough entropy or authentication in mind.

Heres what the PHP: Sessions and security docs suggest:

Developers must not use long life session ID for auto login as it increases risk of stolen session. Auto login should be implemented by developer. Use secure one time hash key as auto login key using cookie. Use secure hash stronger than SHA-2. e.g. SHA-256 or greater with random data from /dev/urandom or like. If user is not authenticated, check the one time auto login key is valid or not. If key is valid, authenticate user and set new secure one time hash key. Auto login key is long lived authentication key, this key should be protected as much as possible. Use path/httponly/secure attributes of cookie to protect. Developer must implement feature that disables auto login and removes unneeded auto login key cookie for users.

I would be careful setting the session lifetime to int max, to avoid risk your generally better off with shorter lived tokens.

As far as the limitations library:

  • multiple device support
  • expiration
  • short lived tokens
  • stateless tokens
  • invalidation (globally or per user)

I would recommend using a library designed specifically with these in mind: tymondesigns/jwt-auth; the jwt-auth package is pretty much the direction I wanted to go with this library, you also get the added advantage it follows the JWT spec.

Another option is using OAuth2, though this might be overkill for a lot of projects.

I have though about deprecating this package in favour of tymondesigns/jwt-auth. Im curious if others have switched to/from this library.

tappleby avatar Aug 08 '15 17:08 tappleby

Thanks for the reply, very interesting stuff, and through your link I also discovered Dingo and Fractal which look useful. Personally I don't want stateless because I need a logout function, and I'll likely will want to allow data to be stored in the session like Parse allows. JWT looks interesting but as far as I can tell it wasn't originally designed for auth, its just for signing any JSON payload to prove it came from the server, so for auth all its doing is signing the JSON containing the user ID. Since the userID isn't encrypted, to me it seems weaker than a session UUID where the user ID is not visible. However you are right about my example session ID possibly not having enough entropy where as I'm sure a JWT signature will have enough, the length is probably configurable in Laravel though.

The multiple device thing is interesting, many services now allow you to see what devices are logged in and allows you to disable their session, e.g. Dropbox. So an auth package that has that feature would be a real benefit.

The session timeout I suppose could be shortened to long enough so the user never has to re-login but short enough so that if they stop using the app then their session expires. I wonder if a month is still within PHP's recommendations?

malhal avatar Aug 08 '15 18:08 malhal

haven't tried them out yet but Dingo and Fractal look very handy.

You are correct about JWT, it is just signing the data so you need to be careful about what you put in it. There is JSON Web Encryption which handles this but it doesnt look like jwt-auth supports it yet.

If you want statefull sessions and the ability to store session data, do you need auth tokens over just using native laravel sessions?

As far as session timeout, a month still feels like a long time. The laravel default is 120 minutes.

A few services I use will expire your web based session after 14 days of not logging in, the experience is a bit different on mobile where the session usually does not expire as quickly.

tappleby avatar Aug 08 '15 19:08 tappleby