3

I am trying to track the actions of all non-logged in users on my site. The aim is to store this activity so that I can add it to their profile when they do create an account.

I am using the Behaviour below to assign new users a cookie and use that cookie as the basis of a "temp user" row in my Users table. This way a user can straight away start interacting with my API.

This seems to work fine. However, I am seeing loads more "temp user" rows being created in my DB than I have visitors to the site - about 2500 compared with around 500 visits yesterday (according to Google Analytics).

Is there anything wrong with the behaviour below, or am I doing something else wrong? Is there a better way?

  <?php
class ApplicationBehavior extends CBehavior
{
    private $_owner;

    public function events()
    {

        return array(
            'onBeginRequest' => 'setCookies'

        );
    }

    public function setCookies()
    {

        $owner = $this->getOwner();

        if ($owner->user->getIsGuest() && !isset(Yii::app()->request->cookies['dc_tempusername'])):
            $tempusername = genRandomString(20);
            $tempuser           = new User();
            $tempuser->username = $tempusername;
            $tempuser->email    = "noemailyet@tempuser.com";
            if (isset(Yii::app()->request->cookies['dc_tempusername'])) {
                $tempuser->name = Yii::app()->request->cookies['dc_tempusername']->value;
            } else {
                $tempuser->name = "CookieBasedTempuser";
            }
            $tempuser->points  = 1;
            $tempuser->firstip = $_SERVER['REMOTE_ADDR'];
            if ($tempuser->validate()) {
                Yii::app()->request->cookies['dc_tempusername'] = new CHttpCookie('dc_tempusername', $tempusername);
                $cookie                                         = new CHttpCookie('dc_tempusername', $tempusername);
                $cookie->expire                                 = time() + 60 * 60 * 24 * 180;
                Yii::app()->request->cookies['dc_tempusername'] = $cookie;
                $tempuser->save();
            } else {
                echo CHtml::errorSummary($tempuser);
            }
        endif;

    }
}
?>
DaveR
  • 2,355
  • 1
  • 19
  • 36
  • 1
    Have you looked at the values in your database for duplicate temp user ip addresses? it seems to me in your code that their ip address is really the only unique identifier. If you see multiple IP addresses then you know your cookie sanity check is failing somewhere – visevo Jul 08 '15 at 15:37
  • Yes, there are lots of duplicates. These seem to belong to IP addresses belonging to big companies, Twitter, Amazon . . . the plot thickens? – DaveR Jul 08 '15 at 18:17
  • 1
    I'm not positive but I am pretty sure it could be that the visitor bots don't have cookies enabled. That would explain why you're getting duplicate entries because the cookie isn't actually being set. – visevo Jul 08 '15 at 21:41
  • Sounds quite possible to me. By visitor bots, to you mean scrapers etc that social media sites use to pull images etc from the site? Would there be an easy way to spot/filter these? – DaveR Jul 08 '15 at 22:12
  • 1
    Technically, yes. I have an idea for you and i'll describe it in an answer below – visevo Jul 08 '15 at 23:59
  • Awesome, really appreciate it. This has been bugging me for months. :) – DaveR Jul 09 '15 at 06:39

1 Answers1

1

Check if cookies are enabled first:
Check if cookies are enabled

If we're correct, every time you see that the user is a guest and does not have a cookie then you're creating a new temp user.

Why not check to see if a cookie is set first, if so then create the temp user? You would end up needing to set 2 cookies: initial temp cookie to check against, and then your 'dc_tempusername' cookie.

You could even go as far as using Browscap to check against known bots:
https://github.com/browscap/browscap-php
http://browscap.org/

You'll need to be able to define browscap in your php.ini

Community
  • 1
  • 1
visevo
  • 791
  • 7
  • 23
  • 1
    This is probably best solution. Just rolled out code and new users are now broadly in line with visitors. The first page view isn't tracked, but that's probably not the end of the world! – DaveR Jul 10 '15 at 08:22
  • Glad to help. Though I'm sure you could tweak your code so that the first page view is still tracked – visevo Jul 10 '15 at 15:04