dre1080 / warden

More than just a user database auth package for FuelPHP
http://dre1080.github.com/warden
MIT License
46 stars 11 forks source link

Remember me not working properly? #43

Closed PrimozRome closed 11 years ago

PrimozRome commented 11 years ago

I am having problem with remember me functionality... i have turned it one:

'rememberable' => array( 'in_use' => true, 'key' => 'warden_remember_me_token', 'ttl' => 1209600, ),

but it keeps signing me out ...

andreoav commented 11 years ago

Can you post where you actually perform the login action?

// For testing purposes, manually set the last parameter to "true"
// and check if the problem persists.
Warden::authenticate($username, $password, true)
PrimozRome commented 11 years ago

yes I am having it set, but still not working!

andreoav commented 11 years ago

Hmm, very weird. I use this functionality and it works without problems. One thing that you can is to check if the "warden_remember_me_token" is being set.

PrimozRome commented 11 years ago

Yes it is set and its weird. Do I need to extend Fuel's session expiration_time (for example to 2 weeks instead of default 2 hours?) in order for this to work? Thanks

andreoav commented 11 years ago

No, you don't need to extend Fuel's default configuration. Can you post your code where you handle the login functionality?

PrimozRome commented 11 years ago

if (Warden::authenticate($val->validated('username'), $val->validated('password'), Input::post('remember', false) ? true : false)) the input post 'remember' is a checkbox placed on my login form

PrimozRome commented 11 years ago

UPDATE:

here is my complete base controller that calls Warden::check() which should also check for remember_me cookie... somehow this is not working for me. Need to debug more, but no time:

<?php

class Controller_Base extends Controller_Template 
{
        public $template = 'templates/template';
    public $current_user;
    public $logged_in;

    /**
    * Runs before every request to this controller.  It sets some template
    * variables which are used throughout the application.
    *
    * @return  void
    */
    public function before()
    {
        parent::before();

        if(Warden::check())
        {
            $user = Warden::current_user();
            $this->current_user = $user;
            $this->logged_in = true;
        }
        else
        {
            $this->current_user = null;
            $this->logged_in = false;
        }

        View::set_global('current_user', $this->current_user);
        View::set_global('logged_in', $this->current_user);
    }
}
PrimozRome commented 11 years ago

OK after some debugging seems like \Cookie::get($this->config['rememberable']['key']) in auto_login() function, which is called at check() returns empty string, even though the cookie is sent.

$this->config['rememberable']['key'] returns 'dewesoft.auth.remember_me' \Cookie::get($this->config['rememberable']['key']) returns empty string even though sent. Check the image here:

screen shot 2013-04-30 at 12 21 57 pm

dre1080 commented 11 years ago

@PrimozRome what is your rememberable.in_use and rememberable.ttl config setting? is there an exit() anywhere while your debugging? you need the whole request cycle to check for a cookie. no exit() or die() in your code.

PrimozRome commented 11 years ago

@dre1080 my config is like this:

array(
    'in_use' => true,
    'key' => 'dewesoft.auth.remember_me',
    'ttl' => 1209600,
),

Yes I had die() in my previous post about debug... But I have now remove it and still seems like that \Cookie::get($this->config['rememberable']['key']) is returning nothing... Check attached image:

![Uploading Screen Shot 2013-05-02 at 2.00.48 PM.png . . .]()

andreoav commented 11 years ago

@PrimozRome No screenshot here... can you upload it again?

PrimozRome commented 11 years ago

Hmm strange... here it goes again: screen shot 2013-05-02 at 2 00 48 pm

bperin commented 11 years ago

Cookie configuration maybe? What happens when you set a cookie manually, close your browser then try to get it again

andreoav commented 11 years ago

@PrimozRome

Try this

PrimozRome commented 11 years ago

@andreoav

thanks on the tips, will try it and see what happens!

andreoav commented 11 years ago

@PrimozRome One thing I found here while revising the code. As you stated in #33, your app is based on a user-permission system, right?

Did you completely remove the roles? The following code handles the auto login functionality:

public function auto_login($role = null)
{
    if (($token = \Cookie::get($this->config['rememberable']['key']))) {
      $user = \Model_User::find_by_remember_token($token);

      if ($user) {
        if ($this->has_access($role, $user)) {
          // Complete the login with the found data
          $this->complete_login($user);

          // Automatic login was successful
          return true;
        }
      }
    }

    return false;
}

As you can see, it uses the has_access method, and this method needs roles to work.

PrimozRome commented 11 years ago

No I still use roles, I just removed relations between roles and permissions and instead setup a relation between users and permissions so I have user-based permissions system, instead role-based permissions...

That said, the auto_login function is the same as in main repo... I only changed the function where can() and cannot() functionality is verified based on user's permissions.

andreoav commented 11 years ago

@PrimozRome Something new with this issue?

PrimozRome commented 11 years ago

@andreoav yes I have some news but no conclusions...

Create an action that does not uses the login system, a public action. Inside this action put something like this: \Debug::dump(\Warden::check()); Without being logged in, navigate to this action... the result must be false

Done and I got false

Sign in and navigate to actiona again... the result must be true

Done and got true

Close your browser, maybe restart the server too. Navigate one more time to that action... the result must be true again.

Done and got true again... But then if I just leave the app idle for god knows how much time (I assume as long as fuel session timeout is set), the check returns false... should still remember me right?

andreoav commented 11 years ago

@PrimozRome, @dre1080 might have a more precise answer but I suppose that you must be logged in for the duration you set to the cookie.

The fuel session timeout it's only a default option, Warden uses the ttl that is set in your warden config file.

I have a big ttl in my app and I didn't have problems so far.

PrimozRome commented 11 years ago

What is your ttl setting? Mine is 1209600... For my remember_me cookie the expiration date is Thu May 16 14:08:56 2013 so the ttl setting is large enough, but Warden::check() still returns false after while...

The problem here is Fuel for some reason doesn't reed my remember_me cookie. It's there but \Cookie::get('dewesoft.auth.remember_me') returns null. Check this screenshot where you can see sent cookies, my test controller code and output... It reads other cookies but doesn't want to read remember_me cookie. I am completely out of idea here!

screen shot 2013-05-07 at 9 56 35 am

PrimozRome commented 11 years ago

Well would you believe it!!! I finally found out the problem... it's a problem in remember me cookie name. I have used dots in my remember me cookie name 'dewesoft.auth.remember_me'. Renaming this cookie into something that doesn't include dots worked!

Then I Googled and find out this article stating that PHP cookies are not allowed to use dots in cookie names: http://harrybailey.com/2009/04/dots-arent-allowed-in-php-cookie-names/. Whoooot?

andreoav commented 11 years ago

Nice, I did not think it could be the name of the problem.

dre1080 commented 11 years ago

Ahh, glad to see the issue was solved