Jump to content

Login system doesn't log me in


dannon

Recommended Posts

Hello, my login system sometimes doesn't log me in. I have been trying to solve this for a past couple of days, and I can't figure out whats wrong as sometimes it works and sometimes it doesn't.

For my website, I use an MVC, and in my Model superclass I initiate the user class.

The User class logs the user in using a constructor: 

function __construct() {
        //print_r($_SESSION);
        if (!isset($_SESSION['user_data']) || $_SESSION['user_data']['loggedIn'] === false) {
            if (isset($_COOKIE['rm_session'])) {
                $cookieInfo = explode("-", $_COOKIE['rm_session']);
                if ($this->checkCookie($cookieInfo[0], $cookieInfo[1])) {
                    $this->updateCookie($cookieInfo[0]);
                    $this->loginId($this->getId($cookieInfo[0]));
                    return;
                }
            }
            $this->loginGuest();
        }
    }
 

This checks if the session is set, if not it will check the cookie.

Here is my check cookie function:

public function checkCookie($username, $token) {
 
        $sql = "SELECT token, time FROM remember_auths WHERE username = :username ORDER BY time DESC";
        $sth = Model::$db->preparedQuery($sql, array(
            ":username" => $username,
        ));
        $data = $sth->fetch(PDO::FETCH_ASSOC);
        if (!empty($data)) {
            if ($this->validateString($token, $data['token'])) {
                $time = time() - strtotime($data['time']);
                if ($time < 2592000) {
                    return true; //all good!
                } else {
                    echo "times are wrong!";
                    return false; //cookie auth too old | can be checked in query?
                }
            } else {
                echo "invalid tokens";
                return false; //invalid token
            }
        } else {
            echo "cookie not found";
            return false; //no cookie found
        }
    }

When the website logs the user in, it updates the cookie. Here is the function for that:

public function updateCookie($username) {
        $randomString = $this->generateString();
        setcookie("rm_session", $username . "-" . $randomString, strtotime('+1 month'), "/");
 
        Model::$db->preparedQuery("INSERT INTO remember_auths (username, token) VALUES(:username, :token)", array(
            ":username" => $username,
            ":token" => $this->cryptString($randomString)
        ));
    }

For some reason, this login system doesn't log the user in sometimes when the user revisits. For debugging, I have echo'ed out where the login system fails, and it seems that the tokens do not match.

I can't figure out what is causing this as I am saving the cookie and the token into the database in the same function. It seems as if half of the function gets called, and the other doesn't. How can I fix this?

 

Thank you in advance.

 

Also sorry if my code is horrible.

Edited by dannon
Link to comment
Share on other sites

do you have php's error_reporting set to E_ALL and display_errors set to ON so that things like header errors on the setcookie() statement would be reported and displayed?

 

you may be outputting something on the page(s) that is preventing the setcookie() statement from working, depending on how you are reaching the code.

 

you should log the token values with a time stamp so that you can determine which ones are the correct ones/what order they are generated in.

Link to comment
Share on other sites

do you have php's error_reporting set to E_ALL and display_errors set to ON so that things like header errors on the setcookie() statement would be reported and displayed?

 

you may be outputting something on the page(s) that is preventing the setcookie() statement from working, depending on how you are reaching the code.

 

you should log the token values with a time stamp so that you can determine which ones are the correct ones/what order they are generated in.

As far as I can see, there are no values which are outputted before the cookies are set.

I do have E_ALL and display_errors set to ON. 1 second, I'll try to do the logging of timestamps. I do have a timestamp in my remember_auths table, so I'll just make one for the cookies. 

Edited by dannon
Link to comment
Share on other sites

another possible reason for 'random' operation of cookies/sessions is if the hostname (with or  without the www.) or path in the URL changes, depending on how you arrive at a page and then navigate around. since you are setting the cookie path parameter to a /, that leaves the hostname changing as a possible cause.

 

you may have multiple versions of your url (with/without the www.) in links, redirects, shortcuts, bookmarks, or in your browser history, so you might be starting with one variation of the hostname and it works until you switch to a different variation of the hostname.

Link to comment
Share on other sites

another possible reason for 'random' operation of cookies/sessions is if the hostname (with or  without the www.) or path in the URL changes, depending on how you arrive at a page and then navigate around. since you are setting the cookie path parameter to a /, that leaves the hostname changing as a possible cause.

 

you may have multiple versions of your url (with/without the www.) in links, redirects, shortcuts, bookmarks, or in your browser history, so you might be starting with one variation of the hostname and it works until you switch to a different variation of the hostname.

 

This is what most probably is causing the problem. I am using the RewriteEngine and the URLs are similar to this forum, where it's "example.com/ab/cd".

Seems to be working better when use the domain.

This is what my setcookie function looks like now:

$domain = ($_SERVER['HOST_NAME'] == "localhost" ? "localhost" : "." . DOMAIN);
setcookie("rm_session", $username . "-" . $randomString, strtotime('+1 month'), "/", $domain);

Also my domain creates two PHPSESSID cookies when I go to my website with www. and without. How can I fix this?

Edited by dannon
Link to comment
Share on other sites

Ok, I fixed the PHPSESSIDs by doing this:

$domain = ($_SERVER['HTTP_HOST'] == "localhost" ? false : "." . DOMAIN);
session_set_cookie_params(0, "/", $domain, false, true);

and for some reason the it's still not updating the token cookie on localhost. However it looks like it's working on my domain. I never knew cookies would be such a pain for me. 

What domain should I use for localhost? I tried false, null and localhost, it seems to cause problems for me. 

 

Edit:: nope, still doing it sometimes. Could it be something wrong with my time checking?

Edited by dannon
Link to comment
Share on other sites

Can you save a session without cookies?

Great idea!

I was actually trying following this: http://stackoverflow.com/questions/549/the-definitive-guide-to-forms-based-website-authentication/477578#477578 to try and make my login secure.

 

Could you tell me how I can save sessions? or should I just use session_set_cookie_params() and just set it for a month? Also is it possible to make the session ID update once the user revisits the site?

Edited by dannon
Link to comment
Share on other sites

Also, as sessions are saved on my web server, wouldn't this waste a lot of space if a lot of people use the remember me? because a lot of sessions would need to be saved? I also cannot find a way to save the session.

Link to comment
Share on other sites

Alright then, step by step:

 

Go back to the __constructor method did you start a session_start() function on the page before to call that method? 

 

Because if not, the logic of your code every time will be the same.

Edited by jazzman1
Link to comment
Share on other sites

Alright then, step by step:

 

Go back to the __constructor method did you start a session_start() function on the page before to call that method? 

 

Because if not, the logic of your code every time will be the same.

Ok, I have placed the session_start() into the constructor of my User class. It makes more sense for me to keep it here.

And yes, I have used session_start() in my Bootstrap class which gets called first.

Edited by dannon
Link to comment
Share on other sites

So, if the user is on a session that part of the code has never been executed,right?

if (!isset($_SESSION['user_data']) || $_SESSION['user_data']['loggedIn'] === false) {
            if (isset($_COOKIE['rm_session'])) {
                $cookieInfo = explode("-", $_COOKIE['rm_session']);
                if ($this->checkCookie($cookieInfo[0], $cookieInfo[1])) {
                    $this->updateCookie($cookieInfo[0]);
                    $this->loginId($this->getId($cookieInfo[0]));
                    return;
                }
            }
Link to comment
Share on other sites

 

So, if the user is on a session that part of the code has never been executed,right?

if (!isset($_SESSION['user_data']) || $_SESSION['user_data']['loggedIn'] === false) {
            if (isset($_COOKIE['rm_session'])) {
                $cookieInfo = explode("-", $_COOKIE['rm_session']);
                if ($this->checkCookie($cookieInfo[0], $cookieInfo[1])) {
                    $this->updateCookie($cookieInfo[0]);
                    $this->loginId($this->getId($cookieInfo[0]));
                    return;
                }
            }

Yes.

Edited by dannon
Link to comment
Share on other sites

What happens further in that __construct (), when the user is on a session?

 

Nothing. I just use it to log the user in. 

 

The User class is initiated in my Model class. The Model is loaded before my Controller class which collects all of the information and then renders it using the View class.

Should I post the whole User class for you? I don't really want to because I think it's badly coded and I don't want to burn your eyes.

Edited by dannon
Link to comment
Share on other sites

php_flag display_errors on
php_value error_reporting 9999
 
RewriteEngine On
 
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
 
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]

I make it so the url is like this: example.com/controller/controller_function

Edited by dannon
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.