title: how to correctly authorise website logins when client uses multiple IP addresses
body: <p>I have a custom website login system built in 2015 that works very well, it appears as far as I can tell to give a high level of security and authenticity between websites, the client logs in to a login website and their details are saved to a session and then the client is transfered to a destination website, where they carry out their actions. </p>
  
  <p>The security takes several key values and authenticates them on every page load to detect inconsistencies, this includes:</p>
  
  <ul>
  <li>hash containing amongst other things their browser key (if given)</li>
  <li>hash of the clients nonce generated once for each succeessful login.</li>
  <li>IP address</li>
  <li>date of login and last action taken</li>
  <li>Database recording and tracking of all of the above details. </li>
  </ul>
  
  <p>This works on the basis that if a client is logged in and changes any of the above values somehow, that the authentication process would detect the inconsitency and then drop the authentication. </p>
  
  <p>This works fine as it is, <strong>BUT</strong> I have an issue; two clients are on different systems (one is on a proxy, one is a load balancer) which seem to be swapping around their current IP address <em>mid-session</em>.</p>
  
  <p>I know IP addresses can and do swap and change but I considered for a fairly small user base (~250) this would be an edge case. I did/do not expect IP addresses to change mid-session (ie once they've logged into the authentication website but before logging into their destination website, or while on the destination website).</p>
  
  <p>I had not considered such things as Proxy connections and Load Balancers. </p>
  
  <p>The IP address detection used is <code>PHP</code> based and is this: </p>
  
  <pre><code>public static function IpAddr()
      {
          if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
              $exploded_IP = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
              $ipAddress = array_pop($exploded_IP);
          } elseif (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
              $exploded_IP = explode(',', $_SERVER['HTTP_CLIENT_IP']);
              $ipAddress = array_pop($exploded_IP);
          } elseif (array_key_exists('HTTP_X_FORWARDED', $_SERVER)) {
              $exploded_IP = explode(',', $_SERVER['HTTP_X_FORWARDED']);
              $ipAddress = array_pop($exploded_IP);
          } elseif (array_key_exists('HTTP_FORWARDED_FOR', $_SERVER)) {
              $exploded_IP = explode(',', $_SERVER['HTTP_FORWARDED_FOR']);
              $ipAddress = array_pop($exploded_IP);
          } else {
              $ipAddress = $_SERVER['REMOTE_ADDR'];
          }
          unset($exploded_IP);
          return $ipAddress;
      }
  </code></pre>
  
  <h1>Questions</h1>
  
  <ul>
  <li><p>What is the best way of dealing with these sort of inconsistencies in a secure manner? </p>
  
  <ul>
  <li>Should I still bother recording and using IP addresses as checkable values?</li>
  </ul></li>
  <li><p>Is there any reliable way for the server to "detect" if a user seems to be "floating about" on multiple IP addresses, yet can still be judged to be the authenticated user?</p></li>
  </ul>