Advertisement
Guest User

Untitled

a guest
May 10th, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.14 KB | None | 0 0
  1. <?php
  2. /**
  3.  *
  4.  * Author: Juan Pablo Guereca.
  5.  *
  6.  * Storeless user's session system.
  7.  *
  8.  * Interface:
  9.  *
  10.  * create( <id_user>, <remember_me> )
  11.  *
  12.  * is_alive(): returns false or the id_user
  13.  *
  14.  * destroy(): it just remove the session cookie, the session can't be destroyed, it just expires.
  15.  *
  16.  */
  17.  
  18. class Session {
  19.     const SESSION_PASSWORD_PREVIOUS = \SESSION_PASSWORD_PREVIOUS;
  20.     const SESSION_PASSWORD_CURRENT = \SESSION_PASSWORD_CURRENT;
  21.    
  22.     private static $id_user = 0;
  23.     private static $remember_me = false;
  24.     private static $last_visit_time = 0;
  25.     private static $is_alive = false;
  26.     private static $hash_with_previous_password = false;
  27.    
  28.     const SESSION_ID_NAME = 's';
  29.     const SESSION_ID_VALUE = '%d,%d,%d,%s';
  30.  
  31.     const SESSION_TIME_FRAME_SECONDS = 180; // 3 Minutes
  32.     const REMEMBER_ME_EXPIRICY_DAYS = 7; // 1 week of remember me.
  33.     const NOT_REMEMBER_ME_EXPIRICY_MINUTES = 15;
  34.    
  35.     private function __construct( ) { }
  36.    
  37.     public static function create ( $id_user, $remember_me = false ) {
  38.         //The only way to "erase" a session is setting its id_user in the gobal $BANNED_ID_USER_SESSION.
  39.         //If the id_user is set we return false.
  40.         if( isset( $GLOBALS['BANNED_SESSION_ID_USERS'] ) && isset( $GLOBALS['BANNED_SESSION_ID_USERS'][$id_user] ) ) {
  41.             return false;
  42.         }
  43.        
  44.         $last_visit_time = \time();
  45.        
  46.         $session_hash = self::build_session_hash( $id_user, $last_visit_time, $remember_me  === true ? '1' : '0', self::SESSION_PASSWORD_CURRENT );
  47.         \lib\set_cookie( self::SESSION_ID_NAME, sprintf( self::SESSION_ID_VALUE, $id_user, $remember_me , $last_visit_time, $session_hash ), $remember_me === true ? REMEMBER_ME_EXPIRICY_DAYS : null );
  48.         self::$id_user = $id_user;
  49.         self::$is_alive = true;
  50.     }
  51.    
  52.     public static function is_alive() {
  53.         if( self::$is_alive ) {
  54.             return self::$is_alive;
  55.         }
  56.        
  57.         if ( ! isset( $_COOKIE[ self::SESSION_ID_NAME ] ) ) {
  58.             self::$is_alive = false;
  59.             return false;
  60.         }
  61.        
  62.        
  63.         list( $id_user, $remember_me , $last_visit_time, $session_hash ) = explode( ',', $_COOKIE[ self::SESSION_ID_NAME ] );
  64.  
  65.         //The only way to "erase" a session is setting its id_user in the gobal $BANNED_ID_USER_SESSION.
  66.         //If the id_user is set we return false.
  67.         if( isset( $GLOBALS['BANNED_SESSION_ID_USERS'] ) && isset( $GLOBALS['BANNED_SESSION_ID_USERS'][$id_user] ) ) {
  68.             return false;
  69.         }
  70.        
  71.         $hash_current_session_password = self::build_session_hash( $id_user, $last_visit_time, $remember_me, self::SESSION_PASSWORD_CURRENT );
  72.  
  73.         if( $session_hash !== $hash_current_session_password ) {
  74.             /**
  75.              * After changing the session password the users have hashes generated with the previous password
  76.              * so we check if it match the hash with the previous session password.
  77.              * If it does, we regenerate the hash with the new session password.
  78.              */
  79.             $hash_previous_session_password = self::build_session_hash( $id_user, $last_visit_time, $remember_me, self::SESSION_PASSWORD_PREVIOUS );
  80.  
  81.             if( $session_hash === $hash_previous_session_password ) {
  82.                 /**
  83.                  * The user has a session generated with the previous password.
  84.                  * That's ok but lets set the "hash with previous password" so the keep_alive method
  85.                  * regenerates the session hash with the new password.
  86.                  */
  87.                 self::$hash_with_previous_password = True;
  88.             } else {
  89.                 //This would be a hack attempt
  90.                 self::destroy();
  91.                 self::$is_alive = false;
  92.                 return false;
  93.             }
  94.         }
  95.        
  96.         //Checking if it has expired
  97.        
  98.         if( $remember_me  === '1' ) {
  99.             $max_time = self::REMEMBER_ME_EXPIRICY_DAYS * 86400;
  100.         } else {
  101.             $max_time = self::NOT_REMEMBER_ME_EXPIRICY_MINUTES * 60;
  102.         }
  103.        
  104.         self::$last_visit_time = (int) $last_visit_time;
  105.        
  106.         if( ( self::$last_visit_time + $max_time ) < \time() ) {
  107.             //It has expired
  108.             self::destroy();
  109.             self::$is_alive = false;
  110.             return false;
  111.         }
  112.        
  113.         self::$is_alive = true;
  114.        
  115.         self::$id_user = $id_user;
  116.         self::$remember_me = $remember_me === '1' ? true : false;
  117.        
  118.         return true;
  119.     }
  120.    
  121.     public static function keep_alive() {
  122.         if( self::$is_alive ) {
  123.             //With time frames we avoid setting a new session cookie each request
  124.             $ts = time();
  125.             $current_time_frame = $ts - ( $ts % self::SESSION_TIME_FRAME_SECONDS );
  126.            
  127.             $last_visit_time_frame = self::$last_visit_time - ( self::$last_visit_time % self::SESSION_TIME_FRAME_SECONDS );
  128.            
  129.             if( $current_time_frame !== $last_visit_time_frame || self::$hash_with_previous_password ) {
  130.                 self::create( self::$id_user, self::$remember_me );
  131.             }
  132.         }
  133.     }
  134.    
  135.     public static function destroy() {
  136.         //The session can't really be destroyed because it's not stored.
  137.         //It's just not usable after the expiricy time.
  138.         //All we can do is remove the cookie.
  139.        
  140.         \lib\delete_cookie( self::SESSION_ID_NAME );
  141.     }
  142.    
  143.     public static function get_id_user() {
  144.         return self::$id_user;
  145.     }
  146.    
  147.     private static function build_session_hash( $id_user, $last_visit_time, $remember_me, $session_password  ) {
  148.         list( $ip_first_octect ) = \explode( '.', $_SERVER['REMOTE_ADDR'] );
  149.         $user_agent = $_SERVER['HTTP_USER_AGENT'];
  150.        
  151.         return \lib\sha256( $session_password . $id_user . $last_visit_time . $remember_me  . $user_agent . $ip_first_octect );
  152.     }
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement