Welcome Guest, Not a member yet? Register   Sign In
User authentication
#1

[eluser]Nial[/eluser]
I know this has been asked a number of times, but a forum/google search hasn't returned anything useful. I use sessions for my sites administrative backend but would like to introduce a persistent cookie to ensure that users aren't logged out intermittently.

At present, here's how I process logins:
Code:
function process_login($login = NULL) {

        if( !isset($login) ) return FALSE;
        if( count($login) != 2 ) return FALSE;
            
        $username = $login[0];
        $password = $login[1];
        
        $this->CI->db->where('user_name', $username);
        $this->CI->db->where('user_password', md5($password));
        $query = $this->CI->db->get( TBL_USERS );
        
        if ($query->num_rows() == 1) {
            
            $this->CI->session->set_userdata('logged_user', $username);
            return TRUE;
        
        } else {
            
            return FALSE;
        
        }
    }

After that, a call to logged_in shows me whether a user has administrative rights:
Code:
function logged_in()
    {
        if ($this->CI->session->userdata('logged_user') == FALSE) {
            return FALSE;
        } else {
            return TRUE;
        }
    }

What's the best way to implement cookies to ensure logins stay persistent?
#2

[eluser]TheFuzzy0ne[/eluser]
Make the cookie permanent in the config.php file:
Code:
$config['sess_expiration'] = 0;
#3

[eluser]Nial[/eluser]
TheFuzzy0ne, I've done that, but it seems patchy. Occasionally the login will hold for a few hours, occasionally a few minutes. Below is my config file:

Code:
$config['sess_cookie_name']        = 'ci_session';
$config['sess_expiration']        = 0;
$config['sess_encrypt_cookie']    = FALSE;
$config['sess_use_database']    = TRUE;
$config['sess_table_name']        = 'ci_sessions';
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent']    = TRUE;
$config['sess_time_to_update']     = 300;

$config['cookie_prefix']    = "";
$config['cookie_domain']    = ".domain.com"; // This has been set to my actual domain
$config['cookie_path']        = "/";
#4

[eluser]TheFuzzy0ne[/eluser]
That suggests to me that you've somehow broken the cookie. I've found that sometimes certain characters such as slashes can break the cookie, or simply storing too much data in it. However, since you're using the database, I don't know what the problem could be. If I think of anything, I'll let you know.

Are you switching between subdomains at any point?
#5

[eluser]Nial[/eluser]
Nope! No subdomain switching. Here's a snippet of what's being stored for admins on login:

Code:
a:2:{s:15:"redirected_from";s:6:"/admin";s:11:"logged_user";s:4:"Nial";}

I've changed the expiry number to 1296000 (15 days) to keep the size of the session database to a minimum (non-admins are obviously being logged, also). Will records older than the expiry date be removed?
#6

[eluser]TheFuzzy0ne[/eluser]
Looks pretty standard to me.

Yes, any sessions where the last activity is more than 15 days ago will be removed from the database.

The intermittent sessions. Do they still remain in the database or are they cleared? If they are still in the database, that suggests to me that there is a problem with the cookies.

What authentication methods are being used at the beginning of each request? I use a method that refreshes the userdata on each request, and checks to see whether or not the user has been suspended, as I don't want suspended users running around on the site just because they haven't deleted their cookie, so I delete the cookie for them.
#7

[eluser]Nial[/eluser]
I have a restrict function that I use in my admin controller (which holds all of the administrative functionality):

Code:
/**
     *
     * This function restricts users from certain pages.
     * use restrict(TRUE) if a user can't access a page when logged in
     *
     * @access    public
     * @param    boolean    wether the page is viewable when logged in
     * @return    void
     */    
    function restrict($logged_out = FALSE)
    {
        // If the user is logged in and he's trying to access a page
        // he's not allowed to see when logged in,
        // redirect him to the index!
        if ($logged_out && $this->logged_in()) {
            redirect('/admin');
        }
        
        // If the user isn't logged in and he's trying to access a page
        // he's not allowed to see when logged out,
        // redirect him to the login page!
        if ( ! $logged_out && ! $this->logged_in()) {
            $this->CI->session->set_userdata('redirected_from', $this->CI->uri->uri_string()); // We'll use this in our redirect method.
            redirect('/admin/login');
        }
    }

In views that display certain things dependent upon whether the user is logged in as an admin, I just call the logged_in function (shown in my first post).

EDIT: Also, the database entries appear consistent (aren't removed). So it may well be a cookie issue!
#8

[eluser]TheFuzzy0ne[/eluser]
And there's no way that your logout method is somehow being called when it shouldn't be? I would suggest logging calls to your logout method, so you can check the logs to see if that's the cause for the session breaking.
#9

[eluser]Nial[/eluser]
I've noticed multiple records in the database with my logged_user session data in. Could this be causing a conflict? Should I have sess_match_ip set to TRUE? (Note that, in this case, the site has three administrators and no other member accounts).

Also, TheFuzzy0ne, when you mention 'refreshing' user data, would that be (in my case) running the login (process_login) code for setting session data, inside the logged_in function, also?

Code:
$this->CI->session->set_userdata('logged_user', $username);
#10

[eluser]TheFuzzy0ne[/eluser]
No. Each session has a unique ID, so even if you've configured the session library to check user agent and IP address, it still won't match any of the old sessions.




Theme © iAndrew 2016 - Forum software by © MyBB