1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Development IP filtering

Discussion in 'Software' started by :: Phat ::, 11 Feb 2006.

  1. :: Phat ::

    :: Phat :: Oooh shakalaka!

    Joined:
    7 Jun 2002
    Posts:
    4,886
    Likes Received:
    3
    I'be been hunting for ages, obviously any search for a php script with "IP" in it comes up with a LOAD.

    What I'm after, I want a user to be able to click a link on a section of a website, however once they've clicked that link, they should not be allowed to see that section again for a set amount of time.

    I'm guessing I'll need to use a database to log the IP and when the link was clicked.
    So the section on the page will basically need to do the following...?

    Check IP
    Check click time
    variable = "time remaining"
    If click time <XXX then some variable = yes
    If click time >XXX then some variable = no

    Then on the page use an if statement?

    If some variable = yes show this bit
    else

    show "sorry, you cannot view this page for "time remaining" anyone fancy helping me out?
     
  2. eek

    eek CAMRA ***.

    Joined:
    23 Jan 2002
    Posts:
    1,600
    Likes Received:
    14
    How secure does it need to be?
    Bearing in mind that it is possible to spoof ip's if needed, you could just go the simple route and make use of a cookie with a time out of whatever you need?

    This is v raw and will need fixing as my scripts never work first time - probably a semicolon missing somewhere of some other stupid mistake, but it should put you on the right track. I would have tested it myself but too lazy to set up a new database!

    (note: I didn't write the ip checking function so if that doesn't work just use $_SERVER['REMOTE_ADDR'], it'll do ;))

    PHP:
    <?php  /* this function was taken from 
        http://forums.devshed.com/php-development-5/proxy-servers-64009.html
        It may or may not work, could just user $_SERVER['REMOTE_ADDR'] but
        this is more fool proof + accounts for multiple users on same network
        ......aparently!
        */
    function get_client_ip() {
        
    // Get REMOTE_ADDR as the Client IP.
        
    $client_ip = ( !empty($_SERVER['REMOTE_ADDR']) ) ? $_SERVER['REMOTE_ADDR'] : ( ( !empty($_ENV['REMOTE_ADDR']) ) ? $_ENV['REMOTE_ADDR'] : $REMOTE_ADDR );

        
    // Check for headers used by proxy servers to send the Client IP. We should look for HTTP_CLIENT_IP before HTTP_X_FORWARDED_FOR.
        
    if ($_SERVER["HTTP_CLIENT_IP"])
            
    $proxy_ip $_SERVER["HTTP_CLIENT_IP"];
        elseif (
    $_SERVER["HTTP_X_FORWARDED_FOR"])
            
    $proxy_ip $_SERVER["HTTP_X_FORWARDED_FOR"];

        
    // Proxy is used, see if the specified Client IP is valid. Sometimes it's 10.x.x.x or 127.x.x.x... Just making sure.
        
    if ($proxy_ip)
        {
            if ( 
    preg_match("/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/"$proxy_ip$ip_list) )
            {
                
    $private_ip = array('/^0\./''/^127\.0\.0\.1/''/^192\.168\..*/''/^172\.16\..*/''/^10.\.*/''/^224.\.*/''/^240.\.*/');
                
    $client_ip preg_replace($private_ip$client_ip$ip_list[1]);
            }
        }

        
    // Return the Client IP.
        
    return $client_ip;
    }

    $ip get_client_ip(); // get ip addr
    $time time(); // current time (in seconds)
    $timeout 3600//timeout in seconds
    $tc = -1;

    $mysqli = new mysqli("localhost""my_user""my_password""database"); // connect to db
    $query "SELECT time_clicked FROM table WHERE ip = '$ip'";

    if (
    mysqli_connect_errno()) { // if can't connect...
        
    printf("Connect failed: %s\n"mysqli_connect_error());
        exit();
    }
     
    if (
    $result $mysqli->query($query)) { // check to see if have visted before

        
    while ($obj $result->fetch_object()) {
            
    $tc $obj->time_clicked// if so, time of last visit is selected
        
    }

        
    $result->close();
    }

    if (
    $tc != -1) { // if been here before...
        
    $timeleft $tc $timeout $time;
        if (
    $timeleft 0)) { // and still have to wait...
            
    echo "sorry, you cannot view this page for ".date("H:i:s",$timeleft); // show this message,
        
    } else {
            echo 
    "Welcome back"// otherwise show welcome back and update table with new time
            
    $mysqli->query("UPDATE table SET time_clicked = '$time' WHERE ip = '$ip'");
        }
    } else { 
    // not been here before?...
        
    echo "Welcome, this is your first time here!"// welcome + add to database
        
    $mysqli->query("INSERT INTO table (ip, time_clicked) VALUES ('$ip','$time')");
    }

    $mysqli->close(); // close db conn
    ?>
    Hope it helps!
     
  3. :: Phat ::

    :: Phat :: Oooh shakalaka!

    Joined:
    7 Jun 2002
    Posts:
    4,886
    Likes Received:
    3
    It doesn't need to be superbly secure as the IP's will be tracked throughout the site anyway, and even if someone was to try and force the system a pattern would appear anyway. I'll look into the code you've posted.

    May need a little bit more help with the code though! I like the first visit function, I could include a link to the FAQ etc on that section, however, I only want the IP logged & blocked after they click on a link and are taken to the next page, so I assume I just put the "Insert into table" code on that page instead.

    The only reason for the delay is to stop someone using a script to force a row of numbers through a php script thats going to be running on the link.
     
  4. eek

    eek CAMRA ***.

    Joined:
    23 Jan 2002
    Posts:
    1,600
    Likes Received:
    14
    Yep :)
     
  5. :: Phat ::

    :: Phat :: Oooh shakalaka!

    Joined:
    7 Jun 2002
    Posts:
    4,886
    Likes Received:
    3
    Cheers, I'll take a stab at it in work tomorrow :)

    I'll let you know how I get on :D
     
  6. :: Phat ::

    :: Phat :: Oooh shakalaka!

    Joined:
    7 Jun 2002
    Posts:
    4,886
    Likes Received:
    3
    I get the following error -

    Fatal error: Cannot instantiate non-existent class: mysqli /public_html/test/sqltest.php on line 45
     
  7. :: Phat ::

    :: Phat :: Oooh shakalaka!

    Joined:
    7 Jun 2002
    Posts:
    4,886
    Likes Received:
    3
    I've since discovered that my server does not support the mysqli function -
     
  8. eek

    eek CAMRA ***.

    Joined:
    23 Jan 2002
    Posts:
    1,600
    Likes Received:
    14
    try removing the 'i' :)

    mysqli in PHP 5+ only
    mysql is the old one

    I believe the code /should/ still be valid though!
     
  9. :: Phat ::

    :: Phat :: Oooh shakalaka!

    Joined:
    7 Jun 2002
    Posts:
    4,886
    Likes Received:
    3
    No, that didn't work :(

    I've been given instructions on another forum, so I'll try them later on :D
     
  10. Hwulex

    Hwulex Minimodder

    Joined:
    1 Feb 2002
    Posts:
    4,007
    Likes Received:
    1
    PHP:
    <?



    class 
    Session {

        protected 
    $chrIP null;

        
    // Period between allowed accesses (in seconds)
        
    const TIME_LIMIT 120;

        protected static 
    $objInstance null;
        protected static 
    $arrRestricted = array(
            
    'restricted.php',
            
    'access.php',
            
    'timelog.php'
        
    );


        protected function 
    __construct() {
            
    $this->canAccess();
        } 
    # end constructor


        
    public function __clone() {
            throw new 
    Exception('Cannot clone a singleton, duh');
        }


        public static function 
    getInstance() {
            if ( 
    self::$objInstance === null ) {
                
    self::$objInstance = new self;
            } 
    # end if

            
    return self::$objInstance;
        } 
    # end method


        
    protected function canAccess() {
            if ( 
    in_array$_SERVER['PHP_SELF'], self::$arrRestricted ) ) {
                list(
    $intTime) = mysql_fetch_arraymysql_query"
                    SELECT intTime
                    FROM AccessLog
                    WHERE chrIP = '
    {$this->getIP()}'
                " 
    ) );
                if ( 
    $intTime && ( $intTime > ( mktime() - self::TIME_LIMIT ) ) ) {
                    throw new 
    Exception('Error - you cannot access this page for another '.( ( $intTime self::TIME_LIMIT ) - mktime() ).' seconds.');
                } else {
                    
    mysql_query"
                        INSERT INTO AccessLog (chrIP, intTime)
                        VALUES ('
    {$this->getIP()}', '".mktime()."')
                    " 
    );
                } 
    # end if
            
    # end if
        
    # end method


        
    public function getIP() {
            if ( 
    $this->chrIP === null ) {
                
    // Get REMOTE_ADDR as the Client IP.
                
    $client_ip = ( !empty($_SERVER['REMOTE_ADDR']) ) ? $_SERVER['REMOTE_ADDR'] : $_ENV['REMOTE_ADDR'];
        
                
    // Check for headers used by proxy servers to send the Client IP. We should look for HTTP_CLIENT_IP before HTTP_X_FORWARDED_FOR.
                
    if ($_SERVER["HTTP_CLIENT_IP"]) {
                    
    $proxy_ip $_SERVER["HTTP_CLIENT_IP"];
                } elseif (
    $_SERVER["HTTP_X_FORWARDED_FOR"]) {
                    
    $proxy_ip $_SERVER["HTTP_X_FORWARDED_FOR"];
                }
        
                
    // Proxy is used, see if the specified Client IP is valid. Sometimes it's 10.x.x.x or 127.x.x.x... Just making sure.
                
    if ($proxy_ip) {
                    if ( 
    preg_match("/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/"$proxy_ip$ip_list) ) {
                        
    $private_ip = array('/^0\./''/^127\.0\.0\.1/''/^192\.168\..*/''/^172\.16\..*/''/^10.\.*/''/^224.\.*/''/^240.\.*/');
                        
    $client_ip preg_replace($private_ip$client_ip$ip_list[1]);
                    }
                }
        
                
    // Return the Client IP.
                
    $this->chrIP $client_ip;
            } 
    # end if

            
    return $this->chrIP;
        } 
    # end method


    # end class


    ?>
    Class based solution. To implement, just stick all that in a file (ie; session.php) and include the file at teh top of the page. Then, just call Session::getInstance(); at the top of your script. Only script defined in the $arrRestricted array will have this time based access security. This means you can just execute this line of code in a single common include in all files and have it only check the ones you want.

    This is a session class by the way, so anything else to do with the user's session could also be contained within this class, such as login, userid, session string, etc.

    Might be of some help. :)


    Note: getIP() method nicked from eek's solution as it looks good enough. :)

    Note: Will probably only work in PHP5.
     
  11. eek

    eek CAMRA ***.

    Joined:
    23 Jan 2002
    Posts:
    1,600
    Likes Received:
    14
    I stole it first ;) :p :lol:
     

Share This Page