Announcement

Collapse
No announcement yet.

How to Create 2 User ID's?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to Create 2 User ID's?

    When a user is stored in the database he gets ID's starting from one. For instance page.php?userID=1

    This seems to be easy to manipulate and therefore I created another column in the database for another unique ID that will be used in the URL instead. I want your opinions that if it is worth doing this or is it pointless? Also, is it good enough to use?
    The code below is an example for something else but seems to be a good choice.
    Code:
    function randUserId() {
        return strtr(
            base64_encode(
                random_bytes(9)
            ),
            '+/',
            '-_'
        );
    }

  • #2
    If you want to store this in a database, use the UNIQUE constraints and any attempt to insert a duplicate value in a UNIQUE column will cause MySQL to throw Error No = 1062. Therefore, you can trap this and retry the value generation process.

    It is beneficial to have non-sequential numbers for database keys while using a security-by-obscurity approach to URL parameters. If you have your clients numbered sequentially from 1,2,3,...it will be quite easy to guess the next sequence. When random keys are used the risk of hacking gets reduces since the hackers is impossible to guess your client's identity and steal your database.

    The strtr() code isn't necessary according to me. Base64_encode() will give you URL-safe values for the random string.

    Comment


    • #3
      Following is one of my thought experiments that focuses on random and unique keys -

      Code:
      <?php // demo/random_unique_string.php
      /**
       * Generate a short unique random string for use as some kind of key.
       *
       * We deliberately omit look-alike letters like o and 0, I and 1.
       * If lower case letters are included, it's wise to omit lower-case l.
       *
       * In some fonts we might want to omit s,5 and z,2.
       *
       * Note that the data base must have the rand_key field defined as "unique"
       * Note that the length argument must match throughout so we define() it.
       */
      error_reporting(E_ALL);
      echo "<pre>";
      
      
      define('ARG_LENGTH', 7);
      
      
      Class Randu
      {
          public $keys, $errs, $cnt;
          protected $mytable  = 'myKeys';
          protected $mycolumn = 'rand_key';
      
          public function __construct()
          {
              $this->keys = array();
              $this->errs = array();
              $this->cnt  = -1;
      
              // DATABASE CONNECTION AND SELECTION VARIABLES - GET THESE FROM YOUR HOSTING COMPANY
              $db_host = "localhost"; // PROBABLY THIS IS OK
              $db_name = "??";
              $db_user = "??";
              $db_word = "??";
              
              // OPEN A CONNECTION TO THE DATA BASE SERVER AND SELECT THE DB
              $this->mysqli = new mysqli($db_host, $db_user, $db_word, $db_name);
      
              // DID THE CONNECT/SELECT WORK OR FAIL?
              if ($this->mysqli->connect_errno)
              {
                  $err
                  = "CONNECT FAIL: "
                  . $this->mysqli->connect_errno
                  . ' '
                  . $this->mysqli->connect_error
                  ;
                  trigger_error($err, E_USER_ERROR);
              }
      
      
              // IN REAL LIFE, THIS WOULD BE A PERMANENT TABLE
              $len = ARG_LENGTH;
              $sql
              =
              "
              CREATE TEMPORARY TABLE $this->mytable
              ( id                 INT                   NOT NULL AUTO_INCREMENT PRIMARY KEY
              , $this->mycolumn    VARCHAR($len)  UNIQUE NOT NULL DEFAULT '?'
              )
              ENGINE=MyISAM DEFAULT CHARSET=ascii
              "
              ;
              // IF mysqli::query() RETURNS FALSE, LOG AND SHOW THE ERROR
              if (!$res = $this->mysqli->query($sql))
              {
                  $err
                  = 'QUERY FAILURE:'
                  . ' ERRNO: '
                  . $this->mysqli->errno
                  . ' ERROR: '
                  . $this->mysqli->error
                  . ' QUERY: '
                  . $sql
                  ;
                  trigger_error($err, E_USER_ERROR);
              }
          }
      
          // FUNCTION TO MAKE A RANDOM STRING
          public function random_string($length)
          {
              // POSSIBLE COMBINATIONS > HUNDREDS OF MILLIONS IF LENGTH > 6
              //           1...5...10...15...20...25...30.
              $alphabet = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
              $strlen   = strlen($alphabet);
              $string   = NULL;
              while(strlen($string) < $length)
              {
                  $random = mt_rand(0,$strlen);
                  $string .= substr($alphabet, $random, 1);
              }
              return($string);
          }
      
          // FUNCTION TO ENSURE THE RANDOM STRING IS UNIQUE
          public function make_random_key()
          {
              $key = NULL;
              $this->cnt++;
      
              // GENERATE A UNIQUE AND RANDOM TOKEN
              while ($key == NULL)
              {
                  $key = $this->random_string(ARG_LENGTH);
                  $sql = "INSERT INTO $this->mytable ( $this->mycolumn ) VALUES ( '$key' )";
                  $res = $this->mysqli->query($sql);
      
                  // IF THERE IS A QUERY ERROR
                  if (!$res)
                  {
                      // THE EXPECTED QUERY ERROR WOULD BE A DUPLICATE VALUE, NULLIFY THE KEY AND START OVER
                      if ($this->mysqli->errno == 1062)
                      {
                          // trigger_error("1062 Duplicate Key Event: $key at " . number_format($this->cnt), E_USER_NOTICE);
                          echo PHP_EOL   . "1062 Duplicate Key Event: $key at " . number_format($this->cnt);
                          $this->errs[$this->cnt] = $key;
                          $key = NULL;
                      }
                      // OTHER UNEXPECTED QUERY ERROR
                      else
                      {
                          $err
                          = 'QUERY FAILURE:'
                          . ' ERRNO: '
                          . $this->mysqli->errno
                          . ' ERROR: '
                          . $this->mysqli->error
                          . ' QUERY: '
                          . $sql
                          ;
                          trigger_error($err, E_USER_ERROR);
                      }
                  }
              }
              $this->keys[$this->cnt] = $key;
              return $key;
          }
      
      }
      
      
      // MAKE LOTS OF UNIQUE AND RANDOM STRINGS
      $num = 0;
      $max = 100000;
      $ran = new Randu;
      $aaa = time();
      while ($num < $max)
      {
          $thing = $ran->make_random_key();
          $num++;
      }
      
      // SHOW THE WORK PRODUCT
      $zzz = time();
      $lap = $zzz - $aaa;
      echo PHP_EOL . "CREATED $max UNIQUE KEYS IN $lap SECONDS" . PHP_EOL;
      echo PHP_EOL . number_format(count($ran->errs)) . " DUPLICATE KEYS";
      echo PHP_EOL;
      print_r($ran->errs);
      echo PHP_EOL ;
      // print_r($ran->keys);

      Comment


      • #4
        Thanks, Gary. It's good to see the examples.

        Even I am not really expert and the less code it takes to do something the better. So, I would probably stick to what I have if it's acceptable by experts like you.

        Comment


        • #5
          Go with "simpler is equal to better."

          There is also a per-request unique string available in $_SERVER["UNIQUE_ID"]
          http://httpd.apache.org/docs/current...unique_id.html
          You can go through the link.

          Comment

          Working...
          X