It is currently Tue Mar 19, 2024 1:11 am



Reply to topic  [ 7 posts ] 
Integrating PHPbb3 authentication into a website 
Author Message
Felix Rex
User avatar

Joined: Fri Mar 28, 2003 6:01 pm
Posts: 16646
Location: On a slope
Reply with quote
Post Integrating PHPbb3 authentication into a website
So I spent quite a bit of time pulling apart the authentication mechanism that phpbb3 uses. First... if you're going to do this... do it BEFORE you build your own authentication engne. :?

Not surprisingly, there isn't much documentation outside of code comments. However, basically it's not possible to just include files and have access to phpbb3 authentication. This is unfortunate... if they had build their auth system more modularly, it would've been a cinch.

At any rate, the way the auth system works is that when you log in, it creates a row in a table with a bunch of user and session information. In a default installation, the table name is phpbb_sessions. The authentication system then basically passes the sid around via GET, though it's smart enough out of the box to pull it out of a session variable. In fact, phpbb seems to take all global arrays and stick them together into one big array.

Once the sid is retrieved, it then pulls the session info out of the db table and verifies that the ip address and browser string are the same. This handles page-to-page validation. This leaves room for MITM attacks and session hijacking, but it's no easier than if you pass the username/password every page refresh.

I ended up having to write my own methods to validate the passed sid. I also made a slight mod to the session.php class to write the sid into $_SESSION. Passing a sid across pages on my site would have required way too much work. This allowed me to pick up the sid and validate and, if you went back to the forum, the forum was smart enough to pick up the session sid on its own, maintaining logged-in status.

Logging out is relatively simple... I just bastardized the session_kill method of the session class from session.php. This basically involves deleting the session from the sessions table and unsetting cookies that may exist. I also updated the last_visit field in the phpbb users table.

I still need to pull apart the login process so I can clone it. I'll probably post full code when I'm done and verify functionality more thoroughly.

_________________
They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety.


Mon Feb 22, 2010 3:18 pm
Profile WWW
Minor Diety
User avatar

Joined: Tue Apr 01, 2003 10:23 am
Posts: 3956
Location: Amsterdam
Reply with quote
Post Re: Integrating PHPbb3 authentication into a website
Is it very different from phpbb 2.x? Or don't you have any experience with that?

_________________
Melchett: As private parts to the gods are we: they play with us for their sport!


Mon Feb 22, 2010 3:25 pm
Profile
Felix Rex
User avatar

Joined: Fri Mar 28, 2003 6:01 pm
Posts: 16646
Location: On a slope
Reply with quote
Post Re: Integrating PHPbb3 authentication into a website
I didn't really look too much into 2.x authentication, so I can't be positive. Looking at the table structure, it looks like the sid/session structure is probably the same. I don't know how 2.x code compares to the 3.x code, but I imagine it's probably fairly similar.

_________________
They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety.


Mon Feb 22, 2010 3:27 pm
Profile WWW
Felix Rex
User avatar

Joined: Fri Mar 28, 2003 6:01 pm
Posts: 16646
Location: On a slope
Reply with quote
Post Re: Integrating PHPbb3 authentication into a website
Ok, I seem to have finally gotten authentication working, at least in a world without subdomains. I'm afraid that adding subdomains may screw up sessions, in which case I may have to move everything from sessions into cookies.

All the modifications I made to phpbb were limited to the sessions.php page, which is good. It's also not actually all that much code, though I'm not especially happy with one part

Mod 1:
add session_start(). I'm not happy about this one... I'm not sure if it's going to have unintended consequences.
starting at line 14 of includes/sessions.php
Code:
if (!defined('IN_PHPBB'))
{
   exit;
}
session_start(); //new code


Mod 2:
Pick up a session sid. If the website sets this session variable, this is how phpbb picks it up.
starting at line 259
Code:
      else
      {
         $this->session_id = $_SID = request_var('sid', '');
         if(!$this->session_id && $_SESSION['sid'])   //clankiller mod to allow a clankiller login to transfer to phpbb
            $this->session_id = $_SESSION['sid'];
         $SID = '?sid=' . $this->session_id;
      }


Mod 3:
This final mod is the first I made, and allows a login into PHPBB to be picked up by my website. This eliminated the need to deal with passing around a GET var.
starting at line 816, at the end of the session_create method.
Code:
//set clankiller validation session
         $_SESSION['sid'] = $this->session_id;


Those are all the changes in phpbb3. I tried to limit these changes as much as I possible could, though that ended up with me having to do more work on the website end. The next post will cover the code in the website half.

_________________
They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety.


Wed Feb 24, 2010 8:55 am
Profile WWW
Felix Rex
User avatar

Joined: Fri Mar 28, 2003 6:01 pm
Posts: 16646
Location: On a slope
Reply with quote
Post Re: Integrating PHPbb3 authentication into a website
The clankiller website (new version) uses a user class for authentication and access rights. Within the class there's an authenticate class that actually does the verification of current logged in sessions, or allows a user to log in and out. I had to rewrite the vast majority of this to conform to the phpbb3 way of doing things. I find their way of doing stuff interesting as it's very different from how I handle it normally.

I'll break the code into pieces, as it's about 150 lines of code for the authenticate method.
Code:
   private function authenticate(){
      if($_GET['sid']){
         $this->_sid = $_GET['sid'];
         $_SESSION['sid'] = $this->_sid;
      }
      else if($_SESSION['sid'])
         $this->_sid = $_SESSION['sid'];   

Here I just grab the SID if it's a get var or a session var. Typically I'd never get the sid via get, but that's how I started this whole process and I didn't really see any problem with keeping it. After that I check to see if there's a login attempt.
Code:
      else if($_POST['password'] && $_POST['username']){
         //import some phpbb functions
         global $phpbb_root_path, $phpEx;
         $phpbb_root_path = ROOT .'/subdomains/forums/';
         $phpEx = 'php';
         
         define('IN_PHPBB', true);
         include($phpbb_root_path .'includes/utf/utf_tools.php');
         include($phpbb_root_path .'includes/functions.php');
      
         $sql = 'SELECT user_password, user_id, user_type, user_login_attempts, user_lastvisit '
            .'FROM phpbb_users '
            .'WHERE username_clean = \'' .tools::clean(utf8_clean_string($_POST['username']), 'dbsafe') .'\'';
         $result = app::queryForum($sql);
         if(count($result) == 0){
            $this->logout();
            return;
         }

         //Check password ...
         if(phpbb_check_hash($_POST['password'], $result[0]['user_password'])){
            //reset login attempts
            $sql = 'UPDATE phpbb_users SET user_login_attempts = 0 WHERE user_id = ' .$result[0]['user_id'];
            app::queryForum($sql);

            //check if user is inactive
            if($result[0]['user_type'] == 1 || $result[0]['user_type'] == 2){
               $this->logout();
               return;
            }
            
            //success - set up session
               //generate unique id;
            $sql = 'SELECT config_value, config_name FROM phpbb_config WHERE config_name in (\'rand_seed\', \'rand_seed_last_update\')';
            $config = app::queryForum($sql);
            foreach($config as $row){
               if($row['config_name'] == 'rand_seed')
                  $rand_seed = $row['config_value'];
               if($row['config_name'] == 'rand_seed_last_update')
                  $rand_seed_last_update = $row['config_value'];
            }
            $uniqueID = md5($rand_seed .microtime());
            $seed = md5($rand_seed .$uniqueID .'c');
            
               //update seed?
            if ($rand_seed_last_update < time() - rand(1,10))   
            {
               $sql = 'UPDATE phpbb_config '
                  .'SET config_value = \'' .$seed .'\' '
                  .'   where config_name = \'rand_seed\'';
               app::queryForum($sql);
               
               $sql = 'UPDATE phpbb_config '
                  .'SET config_value = ' .time() .' '
                  .'   where config_name = \'rand_seed_last_update\'';
               app::queryForum($sql);
            }
            $this->_sid = md5(substr($uniqueID, 4, 16));
            unset($uniqueID);

            $sid = $this->_sid; $page = basename($this->_page); $user_id = $result[0]['user_id']; $last_visit = $result[0]['user_lastvisit'];
            $browser = $this->_browser;
            $browser = trim(substr($browser, 0, 149));
            $ip = $this->_IP;
            $sql = 'INSERT INTO phpbb_sessions '
                   .'(session_id, session_page, session_forum_id, session_user_id, session_start, session_last_visit, '
                   .'session_time, session_browser, session_forwarded_for, session_ip, session_autologin, session_admin, session_viewonline) '
                .'VALUES '
                   .'(\'' .$sid .'\', \'' .$page .'\', 0, ' .$user_id .', ' .time() .', ' .$last_visit .', '
                   .time() .', \'' .$browser .'\', \'\', \'' .$ip .'\', 0, 0, 1)';
            app::queryForum($sql);
            session_start();
            $_SESSION['sid'] = $this->_sid;
         }

If it's not obvious, this was a pain in the ass. At first I include as many of the phpbb functions as I can, though the way it's built it made things difficult and I ended up having to just rewrite some code. After importing the phpbb stuff I could, I retrieve some user info, then check the password. This code is almost identical to what phpbb does, though I'm using my own database abstraction layer and cleaning methods.

If the password matches, I clear the login attempts counter for that user, see if the user is inactive, and if all is well, I then go through a convoluted mess of generating a randomized session id. This is right out of phpbb3 as well, but I had to move it all into my code due to how it was written. I even copied the code to update the random seed so that my website doesn't become a weak section in the security.

Next I create the session row, then set the session sid so it's available for future page refreshes.

The next code block is if the password failed:
Code:
         else{
            //Password incorrect - increase login attempts
            $sql = 'UPDATE phpbb_users SET user_login_attempts = user_login_attempts + 1 WHERE user_id = ' .$result[0]['user_id'];
            app::queryForum($sql);
            $this->logout();
            return;
         }

That part is fairly straight forward. The method continues with session validation. I could have integrated this into the login portion, but didn't really want to duplicate the code if I could help it.

Code:
      $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lastvisit, u.user_avatar, u.user_avatar_type, u.user_avatar_width, u.user_avatar_height, s.session_ip, s.session_browser, s.session_last_visit '
         .'FROM phpbb_sessions s, phpbb_users u '
         .'WHERE s.session_id = \'' .strtolower(tools::clean($this->_sid, 'hex')) .'\' '
            .'AND u.user_id = s.session_user_id';

      $result = app::queryForum($sql);
      if(count($result) == 0){
         $this->logout();
         return;
      }
      //validate session info
      if($result[0]['session_ip'] !== $this->_IP || $this->_browser !== $result[0]['session_browser']){
         $this->logout();
         return;
      }
      
      //if user is anonymous, stop
      if($result[0]['username'] == 'Anonymous'){
         $this->logout();
         return;
      }
      //populate user data      
      $this->_isLoggedIn = true;
      $this->_forum_userid = $result[0]['user_id'];
      $this->_userName = $result[0]['username'];
      $this->_email = $result[0]['user_email'];
      $this->_lastVisit = $result[0]['user_lastvisit'];
      $this->_sLastVisit = $result[0]['session_last_visit'];
      $this->_avatar = array(
            'file' => $result[0]['user_avatar'],
            'type' => $result[0]['user_avatar_type'],
            'width' => $result[0]['user_avatar_width'],
            'height' => $result[0]['user_avatar_height']);
      
      //get clankiller user data
      $sql = 'SELECT userid FROM users WHERE phpbb_userid=' .$this->_forum_userid;
      $result = app::query($sql, 0);
      if(count($result) == 0){
         //doesn't exist yet
         $sql = 'INSERT INTO users '
            .'(phpbb_userid) '
            .'VALUES '
            .'(' .$this->_forum_userid .')';
         app::query($sql, 0);
         $sql = 'SELECT userid FROM users WHERE phpbb_userid=' .$this->_forum_userid;
         $result = app::query($sql);
      }
      $this->_userid = $result[0]['userid'];
      
      //wipe anonymous info for this sid
      $sql = 'DELETE
         FROM phpbb_sessions
         WHERE session_id = \'' . $this->_sid . '\'
            AND session_user_id = -1';
      app::queryForum($sql);
      
      if($_POST['action'] == 'logout'){
         $this->logout();
         return;
      }

The first thing I do here is grab session info and validate it. Then I populate user data in the class and grab user-information from my own users table. If the row doesn't exist, I create it.. .this is for people that have created an account in phpbb, but this is the first time they've actually hit clankiller.com since. I don't plan on rewriting the user-registration portion of phpbb... I'll just redirect people there to create an account.

Finally I do some housekeeping, and lastly, if the user hit a logout button, I log the user out. The reason I log out after all this other junk is for logout housekeeping.

Code:
   private function logout(){
      //clear website session
      $_SESSION = array();
      
      //do phpbb cleanup
         //clear db session
         if($this->_sid && $this->_forum_userid){
            $sql = 'DELETE FROM phpbb_sessions '
               .'WHERE session_id = \'' .$this->_sid .'\' '
                  .'AND session_user_id = ' .$this->_forum_userid;
            app::queryForum($sql);
            
            //update last_visit
            $sql = 'UPDATE phpbb_users '
               .'SET user_lastvisit = ' . $this->_sLastVisit .' '
               .'WHERE user_id = ' .$this->_forum_userid;
            app::queryForum($sql);
         }

         //phpbb cookies
         $cookie_expire = $this->time_now - 31536000;
         setcookie('u', '', $cookie_expire);
         setcookie('k', '', $cookie_expire);
         setcookie('sid', '', $cookie_expire);
         unset($cookie_expire);
         
         $this->_isLoggedIn = false;
   }

The clankiller side of logout is pretty easy.. just clear the sessions. PHPbb requires a bit more work, but nothing is exceptionally strange.

And that's how I handle cross-authentication. I haven't played with subdomains yet, so it's possible that subdomains are going to screw up my sessions. If that's the case, hopefully cookies will work. If that doesn't work either... well...crap. The code above will still work as far as sharing a user table and that info, but worst case scenario is the user would have to log in any time they move from the forum to the website or vice versa.

_________________
They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety.


Wed Feb 24, 2010 9:12 am
Profile WWW
Felix Rex
User avatar

Joined: Fri Mar 28, 2003 6:01 pm
Posts: 16646
Location: On a slope
Reply with quote
Post Re: Integrating PHPbb3 authentication into a website
ok, I made a few mistakes. My biggest mistake was not checking for session timeout. Basically, if a session was in the sessions table from a month ago, as long as your authenticated information still matched that session, you'd be auto-logged in. Even though there's an expiration on the login time.

The second mistake was that I never cleaned out the session table. If I'd covered the second, the first would never have come up. :roll:

Anyway, rather than talk about changes, I basically added some code to the authenticate() and logout() methods. The logout() does the session table trim... phpbb has this as part of a cron-type deal, but I don't expect enough login attempts to cause any serious sql load.

Also please note that I've omitted some niceties. There's no autologin, for instance, and when a session expires, I don't update a user's profile accordingly. PHPbb does, but not my website. There's also a lot of decision blocks that I could probably stick together in the authenticate method. For now I'm leaving it broken up for ease of troubleshooting. I may eventually concatenate all that stuff.

Code:
   private function authenticate(){
      if($_GET['sid']){
         $this->_sid = $_GET['sid'];
         $_SESSION['sid'] = $this->_sid;
      }
      else if($_SESSION['sid'])
         $this->_sid = $_SESSION['sid'];      
      else if($_POST['password'] && $_POST['username']){
         //import some phpbb functions
         global $phpbb_root_path, $phpEx;
         $phpbb_root_path = ROOT .'/subdomains/forums/';
         $phpEx = 'php';
         
         define('IN_PHPBB', true);
         include($phpbb_root_path .'includes/utf/utf_tools.php');
         include($phpbb_root_path .'includes/functions.php');
         $username = tools::clean(utf8_clean_string($_POST['username']), 'dbsafe');
      
         $sql = 'SELECT user_password, user_id, user_type, user_login_attempts, user_lastvisit '
            .'FROM phpbb_users '
            .'WHERE username_clean = \'' .$username .'\'';
         $result = app::queryForum($sql);
         if(count($result) == 0){
            $this->logout();
            app::log('login', 'Invalid username passed: ' .$username);
            return;
         }

         //Check password ...
         if(phpbb_check_hash($_POST['password'], $result[0]['user_password'])){
            //reset login attempts
            $sql = 'UPDATE phpbb_users SET user_login_attempts = 0 WHERE user_id = ' .$result[0]['user_id'];
            app::queryForum($sql);

            //check if user is inactive
            if($result[0]['user_type'] == 1 || $result[0]['user_type'] == 2){
               $this->logout();
               app::log('login', 'Inactive user attempted login: ' .$username .' (' .$result[0]['user_id']) .')';
               return;
            }
            
            //success - set up session
               //generate unique id;
            $sql = 'SELECT config_value, config_name FROM phpbb_config WHERE config_name in (\'rand_seed\', \'rand_seed_last_update\')';
            $config = app::queryForum($sql);
            foreach($config as $row){
               if($row['config_name'] == 'rand_seed')
                  $rand_seed = $row['config_value'];
               if($row['config_name'] == 'rand_seed_last_update')
                  $rand_seed_last_update = $row['config_value'];
            }
            $uniqueID = md5($rand_seed .microtime());
            $seed = md5($rand_seed .$uniqueID .'c');
            
               //update seed?
            if ($rand_seed_last_update < time() - rand(1,10))   
            {
               $sql = 'UPDATE phpbb_config '
                  .'SET config_value = \'' .$seed .'\' '
                  .'   where config_name = \'rand_seed\'';
               app::queryForum($sql);
               
               $sql = 'UPDATE phpbb_config '
                  .'SET config_value = ' .time() .' '
                  .'   where config_name = \'rand_seed_last_update\'';
               app::queryForum($sql);
            }
            $this->_sid = md5(substr($uniqueID, 4, 16));
            unset($uniqueID);

            $sid = $this->_sid; $page = basename($this->_page); $user_id = $result[0]['user_id']; $last_visit = $result[0]['user_lastvisit'];
            $browser = $this->_browser;
            $browser = trim(substr($browser, 0, 149));
            $ip = $this->_IP;
            $sql = 'INSERT INTO phpbb_sessions '
                   .'(session_id, session_page, session_forum_id, session_user_id, session_start, session_last_visit, '
                   .'session_time, session_browser, session_forwarded_for, session_ip, session_autologin, session_admin, session_viewonline) '
                .'VALUES '
                   .'(\'' .$sid .'\', \'' .$page .'\', 0, ' .$user_id .', ' .time() .', ' .$last_visit .', '
                   .time() .', \'' .$browser .'\', \'\', \'' .$ip .'\', 0, 0, 1)';
            app::queryForum($sql);
            $_SESSION['sid'] = $this->_sid;
            //echo 'setting sid ' .$this->_sid .' .. ' .$_SESSION['sid'] .'<br>';
         }
         else{
            //Password incorrect - increase login attempts
            $sql = 'UPDATE phpbb_users SET user_login_attempts = user_login_attempts + 1 WHERE user_id = ' .$result[0]['user_id'];
            app::queryForum($sql);
            app::log('login', 'Incorrect password for user ' .$username .' (' .$result[0]['user_id']) .')';
            $this->logout();
            return;
         }
      }
      if(!$this->_sid)
         return;
      $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lastvisit, u.user_avatar, u.user_avatar_type, u.user_avatar_width, u.user_avatar_height, s.session_ip, s.session_browser, s.session_last_visit, s.session_time '
         .'FROM phpbb_sessions s, phpbb_users u '
         .'WHERE s.session_id = \'' .strtolower(tools::clean($this->_sid, 'hex')) .'\' '
            .'AND u.user_id = s.session_user_id';

      $result = app::queryForum($sql);
      if(count($result) == 0){
         $this->logout();
         return;
      }
      //validate session info
      if($result[0]['session_ip'] !== $this->_IP || $this->_browser !== $result[0]['session_browser']){
         $this->logout();
         return;
      }
      //validate session timeout
      $sql = 'SELECT config_value  FROM phpbb_config WHERE config_name in (\'session_length\')'; //we don't honor autologin settings
      $config = app::queryForum($sql);
      if($result[0]['session_time'] < time() - $config[0]['config_value'] + 60){
         $this->logout();
         return;
      }
      
      //if user is anonymous, stop
      if($result[0]['username'] == 'Anonymous'){
         $this->logout();
         return;
      }
      //populate user data      
      $this->_isLoggedIn = true;
      $this->_forum_userid = $result[0]['user_id'];
      $this->_userName = $result[0]['username'];
      $this->_email = $result[0]['user_email'];
      $this->_lastVisit = $result[0]['user_lastvisit'];
      $this->_sLastVisit = $result[0]['session_last_visit'];
      $this->_avatar = array(
            'file' => $result[0]['user_avatar'],
            'type' => $result[0]['user_avatar_type'],
            'width' => $result[0]['user_avatar_width'],
            'height' => $result[0]['user_avatar_height']);
      
      //get clankiller user data
      $sql = 'SELECT userid FROM users WHERE phpbb_userid=' .$this->_forum_userid;
      $result = app::query($sql, 0);
      if(count($result) == 0){
         //doesn't exist yet
         $sql = 'INSERT INTO users '
            .'(phpbb_userid, username) '
            .'VALUES '
            .'(' .$this->_forum_userid .', \'' .$this->_userName .'\')';
         app::query($sql, 0);
         $sql = 'SELECT userid FROM users WHERE phpbb_userid=' .$this->_forum_userid;
         $result = app::query($sql);
      }
      $this->_userid = $result[0]['userid'];
      
      //wipe anonymous info for this sid
      $sql = 'DELETE
         FROM phpbb_sessions
         WHERE session_id = \'' . $this->_sid . '\'
            AND session_user_id = -1';
      app::queryForum($sql);
      
      if($_POST['action'] == 'logout'){
         $this->logout();
         return;
      }
   }


Code:
   private function logout(){
      //clear website session
      $_SESSION = array();
      
      //do phpbb cleanup
         //clear db session
         if($this->_sid && $this->_forum_userid){
            $sql = 'DELETE FROM phpbb_sessions '
               .'WHERE session_id = \'' .$this->_sid .'\' '
                  .'AND session_user_id = ' .$this->_forum_userid;
            app::queryForum($sql);
            
            //update last_visit
            $sql = 'UPDATE phpbb_users '
               .'SET user_lastvisit = ' . $this->_sLastVisit .' '
               .'WHERE user_id = ' .$this->_forum_userid;
            app::queryForum($sql);
         }

         //phpbb cookies
         $cookie_expire = $this->time_now - 31536000;
         setcookie('u', '', $cookie_expire);
         setcookie('k', '', $cookie_expire);
         setcookie('sid', '', $cookie_expire);
         unset($cookie_expire);
         
         $this->_isLoggedIn = false;
         
         //clean up expired sessions - I'm not going to bother updating the user table with last visit information
         $sql = 'SELECT config_value  FROM phpbb_config WHERE config_name in (\'session_length\')';
         $config = app::queryForum($sql);
         
         $sql = 'DELETE FROM phpbb_sessions WHERE session_time < ' .(time() - $config[0]['config_value']);
         app::queryForum($sql);
   }

_________________
They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety.


Fri Feb 26, 2010 11:18 am
Profile WWW
Felix Rex
User avatar

Joined: Fri Mar 28, 2003 6:01 pm
Posts: 16646
Location: On a slope
Reply with quote
Post Re: Integrating PHPbb3 authentication into a website
ok, so I may have mentioned that I needed to port this authentication scheme to a domain/subdomain setup... ie, clankiller.com for the website end, forums.clankiller.com for the forum side. Well, turns out that bridging sessions across subdomains isn't quite so easy. There's a way to do it by using session_set_cookie_params in php or altering your php.ini, but in some cases that doesn't work. On this host, it doesn't seem to work. Go figure.

So I had to figure out a new way to get this done without using sessions. I started looking at how to create my own session handler that would ignore domains when I realized that this has already been created for me by phpbb. The sessions table is a session management scheme, after all.. I just needed to exploit it properly. So I did.

The idea was still to minimize the alterations I had to do to PHPbb as much as possible. As such, I reverted to a clean copy of session.php... all previous changes with session_start() and all that were removed. All I really needed to do was make it so that phpbb would pick up the sessions I created on the website half. For that, right around like 288 (between the foreach($ips as $ip loop and the $this->load=false; line), I added a small check

Code:
      // ck mod to support cross-subdomain linking
      if(!$this->session_id){
         $sql = 'SELECT session_id, session_time '
            .'FROM ' . SESSIONS_TABLE . ' '
            .'WHERE session_browser = \'' .$this->browser .'\' and session_ip = \'' .$this->ip .'\' AND session_user_id > 1 ORDER BY session_time DESC LIMIT 0,1';
         $result = $db->sql_query($sql);
         $t = $db->sql_fetchrow($result);
         if($t['session_time'] + $config['session_length'] + 60 > time()){
            $this->session_id = $t['session_id'];
         }
         $db->sql_freeresult($result);
      }


The code block only gets executed if a session_id is missing... ie, you just arrived at the forum. At that point I look for an entry in the sessions table that matches the user's ip, browser info, and falls within the session timeout period. If it is, I make that session_id the current user's session id, and bam, done.

The code on the website end didn't change too much. Basically, I removed all the if and else if statements at the top that were looking for the session id passed via GET (pointless anyway) or SESSION (no longer used). Instead, I look only for a posted username/password, else I query the session table in a similar manner to above.

Code:
      else{
         //check if a session from PHPBB exists and is valid
         $sql = 'SELECT config_value FROM phpbb_config WHERE config_name = \'session_length\'';
         $config = app::queryForum($sql);
         $sql = 'SELECT session_id, session_time FROM phpbb_sessions WHERE session_browser = \'' .$this->_browser .'\' and session_ip = \'' .$this->_IP .'\' AND session_user_id > 1 ORDER BY session_time DESC LIMIT 0,1';
         $result = app::queryForum($sql);
         if($result[0]['session_time'] + $config[0]['config_value'] + 60 > time())
            $this->_sid = $result[0]['session_id'];
      }


The rest of the code in my authentication method stays the same.

I'm still testing this, so it's possible I'll make some changes. The 'and sesion_user_id > 1' section is a bit odd to me... I was under the impression that anonymous users were -1, not 1, but haven't had time to fully delve into that yet. I also need to add in code to trim away expired sessions and keep the session table small.

_________________
They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety.


Mon Mar 15, 2010 12:19 pm
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 7 posts ] 

Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware.