session.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <?php
  2. /*
  3. Copyright (c) 2009-2014 F3::Factory/Bong Cosca, All rights reserved.
  4. This file is part of the Fat-Free Framework (http://fatfree.sf.net).
  5. THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
  6. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  7. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  8. PURPOSE.
  9. Please see the license.txt file for more information.
  10. */
  11. namespace DB\Mongo;
  12. //! MongoDB-managed session handler
  13. class Session extends Mapper {
  14. protected
  15. //! Session ID
  16. $sid;
  17. /**
  18. * Open session
  19. * @return TRUE
  20. * @param $path string
  21. * @param $name string
  22. **/
  23. function open($path,$name) {
  24. return TRUE;
  25. }
  26. /**
  27. * Close session
  28. * @return TRUE
  29. **/
  30. function close() {
  31. return TRUE;
  32. }
  33. /**
  34. * Return session data in serialized format
  35. * @return string|FALSE
  36. * @param $id string
  37. **/
  38. function read($id) {
  39. if ($id!=$this->sid)
  40. $this->load(array('session_id'=>$this->sid=$id));
  41. return $this->dry()?FALSE:$this->get('data');
  42. }
  43. /**
  44. * Write session data
  45. * @return TRUE
  46. * @param $id string
  47. * @param $data string
  48. **/
  49. function write($id,$data) {
  50. $fw=\Base::instance();
  51. $sent=headers_sent();
  52. $headers=$fw->get('HEADERS');
  53. if ($id!=$this->sid)
  54. $this->load(array('session_id'=>$this->sid=$id));
  55. $csrf=$fw->hash($fw->get('ROOT').$fw->get('BASE')).'.'.
  56. $fw->hash(mt_rand());
  57. $this->set('session_id',$id);
  58. $this->set('data',$data);
  59. $this->set('csrf',$sent?$this->csrf():$csrf);
  60. $this->set('ip',$fw->get('IP'));
  61. $this->set('agent',
  62. isset($headers['User-Agent'])?$headers['User-Agent']:'');
  63. $this->set('stamp',time());
  64. $this->save();
  65. if (!$sent) {
  66. if (isset($_COOKIE['_']))
  67. setcookie('_','',strtotime('-1 year'));
  68. call_user_func_array('setcookie',
  69. array('_',$csrf)+$fw->get('JAR'));
  70. }
  71. return TRUE;
  72. }
  73. /**
  74. * Destroy session
  75. * @return TRUE
  76. * @param $id string
  77. **/
  78. function destroy($id) {
  79. $this->erase(array('session_id'=>$id));
  80. setcookie(session_name(),'',strtotime('-1 year'));
  81. unset($_COOKIE[session_name()]);
  82. header_remove('Set-Cookie');
  83. return TRUE;
  84. }
  85. /**
  86. * Garbage collector
  87. * @return TRUE
  88. * @param $max int
  89. **/
  90. function cleanup($max) {
  91. $this->erase(array('$where'=>'this.stamp+'.$max.'<'.time()));
  92. return TRUE;
  93. }
  94. /**
  95. * Return anti-CSRF token
  96. * @return string|FALSE
  97. **/
  98. function csrf() {
  99. return $this->dry()?FALSE:$this->get('csrf');
  100. }
  101. /**
  102. * Return IP address
  103. * @return string|FALSE
  104. **/
  105. function ip() {
  106. return $this->dry()?FALSE:$this->get('ip');
  107. }
  108. /**
  109. * Return Unix timestamp
  110. * @return string|FALSE
  111. **/
  112. function stamp() {
  113. return $this->dry()?FALSE:$this->get('stamp');
  114. }
  115. /**
  116. * Return HTTP user agent
  117. * @return string|FALSE
  118. **/
  119. function agent() {
  120. return $this->dry()?FALSE:$this->get('agent');
  121. }
  122. /**
  123. * Instantiate class
  124. * @param $db object
  125. * @param $table string
  126. **/
  127. function __construct(\DB\Mongo $db,$table='sessions') {
  128. parent::__construct($db,$table);
  129. session_set_save_handler(
  130. array($this,'open'),
  131. array($this,'close'),
  132. array($this,'read'),
  133. array($this,'write'),
  134. array($this,'destroy'),
  135. array($this,'cleanup')
  136. );
  137. register_shutdown_function('session_commit');
  138. @session_start();
  139. $fw=\Base::instance();
  140. $headers=$fw->get('HEADERS');
  141. if (($ip=$this->ip()) && $ip!=$fw->get('IP') ||
  142. ($agent=$this->agent()) &&
  143. (!isset($headers['User-Agent']) ||
  144. $agent!=$headers['User-Agent'])) {
  145. session_destroy();
  146. $fw->error(403);
  147. }
  148. $csrf=$fw->hash($fw->get('ROOT').$fw->get('BASE')).'.'.
  149. $fw->hash(mt_rand());
  150. if ($this->load(array('session_id'=>$this->sid=session_id()))) {
  151. $this->set('csrf',$csrf);
  152. $this->save();
  153. }
  154. }
  155. }