Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Simple auth: guest_login usage explanation?
  • What exactly is 'guest_login' => true, and why is it good for? What is the use-case for this thing? Thanks again,
    Primoz
  • A remember me option is very dangerous, it allows a login without credential. If you want to implement it, it's very easy to do it yourself, and call Auth::force_login() with the user_id of the user you want to login.
  • I noticed all of this yesterday when I was working on my auth controller. I use SimpleAuth and I wanted to add "remember me" functionality to it. I have implemented cookies and everything needed for remember me to work. But when reading for user's auth cookie and if cookie is valid and everything, I look up the right user in the DB to set that user as the currently logged in user. But setting current user and making Auth::instance()->check() work afterwards made me realize that Auth::instance()->check() would not work because of the guest user. I have set it do false in SimpleAuth configuration and then it worked. This is my base controller, which checks for currently logged in user (also here: https://github.com/PrimozRome/FuelPHP-starter-app/blob/master/fuel/app/classes/controller/base.php).
     /**
      * 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();
      
      /**
       * 1. check if user logged in
       * 2. if not check if remembered cookie is set and login if possible
       * 3. user not logged in
       */
      if(Auth::check())
      {
       $this->current_user = Model_User::find_by_username(Auth::get_screen_name());
       $this->logged_in = true;
      }
      elseif($user = static::is_remembered())
      {
       if (Auth::check())
       {
        $this->current_user = $user;
        $this->logged_in = true;
       }
      }
      else
      {
       $this->current_user = null;
       $this->logged_in = Auth::check() ? true : false;
      }
      
      View::set_global('current_user', $this->current_user);
      View::set_global('logged_in', $this->current_user);
      
      $this->template->header = View::forge('home/header');
      $this->template->footer = View::forge('home/footer');
     }
     
     /**
      * Check if remember me is set and valid
      */
     protected static function is_remembered()
     {
      \Config::load('simpleauth', true);
      
      $encoded_val = Cookie::get(Config::get('simpleauth.remember_me.cookie_name'));
      
      if ($encoded_val)
      {
       $val = base64_decode($encoded_val);
       list($saltedpasswordhash, $cookie_pass, $login_hash) = explode(':', $val);
       $user = Model_User::find_by_remember_me($cookie_pass);
       $dbpasshash = sha1(sha1($user->password).sha1(Config::get('simpleauth.salt')));
             
       if ($user)
       {
        // set auth session variables
        \Session::set('username', $user->username);
        \Session::set('login_hash', $login_hash);
        \Session::instance()->rotate();   
    
        $user->last_login = time();
        $user->save();
        return $user;
       }
       else
       {
        return false;
       }
      }
    
      return false;
     }
    

    Can you look at is_remembered() static function, if I handle user authentication from cookie in the right manner. Especially the section where I set Auth's session variables. It works but I am still in doubts if I handle everything right.
  • When you post something like this, only post the relevant portions or if you do want to post it completely do it externally on a site like scrapyrd.com. In here there's no need to include the class definition, file docblock, and action_error() & action_404() methods. That keeps your posts readable.
    But setting current user and making Auth::instance()->check() work afterwards made me realize that Auth::instance()->check() would not work because of the guest user. I have set it do false in SimpleAuth configuration and then it worked.
    Why would guest login prevent this from working? I don't see any code here that wouldn't work because of it.
    Can you look at is_remembered() static function, if I handle user authentication from cookie in the right manner. Especially the section where I set Auth's session variables. It works but I am still in doubts if I handle everything right.

    There's a few things very wrong here:
    - Don't put a user's password in a cookie, I don't care how many times you (re-)hash it. Just don't. A password is something very personal you should consider to be a great secret never to be shared or hinted at. You only use a user's password (or whatever relates to it, or part of it) to check when logging in, don't ever transmit it and don't use it for anything else.
    - I can steal your session by just stealing your cookie, I would be able to do everything once I have the cookie. This will even tell me the user's hashed password and the user's current login hash.
    - This won't rotate the user's login-hash, thus keeping it valid as long as the cookie keeps using it. Enlarging the problem from my previous point. You should force a re-login when creating something like this, not re-using an old login.
    - This is logic that should be in the auth driver, not in a controller.
    - $dbpasshash seems useless, even causing errors when the cookie's data is wrong. Remember me functionality is very dangerous, you need to do a lot more research to understand how to implement it safely.
  • I will be careful when posting code up here, thanks for warning! I have edit my original post to fix the code tag.
    There's a few things very wrong here:
    - Don't put a user's password in a cookie, I don't care how many times you (re-)hash it. Just don't. A password is something very personal you should consider to be a great secret never to be shared or hinted at. You only use a user's password (or whatever relates to it, or part of it) to check when logging in, don't ever transmit it and don't use it for anything else.
    - I can steal your session by just stealing your cookie, I would be able to do everything once I have the cookie. This will even tell me the user's hashed password and the user's current login hash.
    - This won't rotate the user's login-hash, thus keeping it valid as long as the cookie keeps using it. Enlarging the problem from my previous point. You should force a re-login when creating something like this, not re-using an old login.
    - This is logic that should be in the auth driver, not in a controller.
    - $dbpasshash seems useless, even causing errors when the cookie's data is wrong. Remember me functionality is very dangerous, you need to do a lot more research to understand how to implement it safely.

    This is what I was afraid of :(. I will go and read couple of articles on how to safely implement remember me function... But I really don't want to write my own driver just to add this. I am not sure if I even know how to write my own driver. Documentation on this is non-existent and I am probably gonna introduce even more bad things... Is it really so bad if this logic is in my base controller? I wish someone has done this already, made it safe and right and ready to use. I know there is Sentry auth package, which does remember me and everything, but this doesn't use Fuel's native Auth, which makes me ask why... confusing! Anyway I don't want to use Sentry since I want to add Ninja Auth's social login as well and this works on top of Fuel's native Auth! Remember me is something so standard today, that really should be in the core of Fuels native Auth!
  • I agree with Jume - i think this "dangerous" moment need to be included in native Auth package.
  • Still no Remember Me? We need this!
  • A guest login is a fake login to allow usage of Group and ACL functionality. As the Auth::member() and Auth::has_access() methods use Auth::instance()->has_access() they need a logged in driver to be able to work. If the user is not logged in it wouldn't be able to work as those would never be called, the non-logged in driver has no user to check the group of or check the ACL. The guest login setting allows a driver to work like it's logged in as "Guest" and return that the current "user" is a member of group "Guests" and probably has access to very little. The Auth::instance()->check() method would (& should) still return false though when it's "logged in" as a guest.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion