我在很多地方寻找解决这个问题的方法,没有运气。我完全失去了,我是修改会话并尝试实现安全会话接口和会话处理程序的新手。我得到的错误是
警告:session_set_save_handler()要求参数1为SessionHandlerInterface,在第124行的C:\ wamp \ www \ SecSessionHandler.php中给出对象。
很抱歉提前发帖!
以下是两个相应的文件:
SecSession.php:
<?php
class SecSession {
/**
* Encryption algorithm
*/
protected $_algo= MCRYPT_RIJNDAEL_128;
/**
* Key for encryption/decryption
*/
protected $_key;
/**
* Key for HMAC authentication
*/
protected $_auth;
/**
* Path of the session file
*/
protected $_path;
/**
* Session name (optional)
*/
protected $_name;
/**
* Size of the IV vector for encryption
*/
protected $_ivSize;
/**
* Cookie variable name of the encryption + auth key
*/
protected $_keyName;
/**
* Generate a random key using openssl
* fallback to mcrypt_create_iv
*/
protected function _randomKey($length=128) {
if(function_exists('openssl_random_pseudo_bytes')) {
$rnd = openssl_random_pseudo_bytes($length, $strong);
if ($strong === true) {
return $rnd;
}
}
return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
}
/**
* Constructor
*/
public function __construct()
{
session_set_save_handler(
array($this, "open"),
array($this, "close"),
array($this, "read"),
array($this, "write"),
array($this, "destroy"),
array($this, "gc")
);
if (!extension_loaded('mcrypt')) {
throw new Exception("The SecureSession class needs the Mcrypt PHP extension, please install it.");
}
}
/**
* Open the session
*
* @param string $save_path
* @param string $session_name
* @return bool
*/
public function open($save_path, $session_name)
{
$this->_path = $save_path.'/';
$this->_name = $session_name;
$this->_keyName = "KEY_$session_name";
$this->_ivSize = mcrypt_get_iv_size($this->_algo, MCRYPT_MODE_CBC);
if (empty($_COOKIE[$this->_keyName]) || strpos($_COOKIE[$this->_keyName],':')===false) {
$keyLength = mcrypt_get_key_size($this->_algo, MCRYPT_MODE_CBC);
$this->_key = self::_randomKey($keyLength);
$this->_auth = self::_randomKey(32);
$cookie_param = session_get_cookie_params();
setcookie(
$this->_keyName,
base64_encode($this->_key) . ':' . base64_encode($this->_auth),
($cookie_param['lifetime'] > 0) ? time() + $cookie_param['lifetime'] : 0,
$cookie_param['path'],
$cookie_param['domain'],
$cookie_param['secure'],
$cookie_param['httponly']
);
} else {
list ($this->_key, $this->_auth) = explode (':',$_COOKIE[$this->_keyName]);
$this->_key = base64_decode($this->_key);
$this->_auth = base64_decode($this->_auth);
}
return true;
}
/**
* Close the session
*/
public function close()
{
return true;
}
/**
* Read and decrypt the session
*/
public function read($id)
{
$sess_file = $this->_path.$this->_name."_$id";
if (!file_exists($sess_file)) {
return false;
}
$data = file_get_contents($sess_file);
list($hmac, $iv, $encrypted)= explode(':',$data);
$iv = base64_decode($iv);
$encrypted = base64_decode($encrypted);
$newHmac = hash_hmac('sha256', $iv . $this->_algo . $encrypted, $this->_auth);
if ($hmac !== $newHmac) {
return false;
}
$decrypt = mcrypt_decrypt(
$this->_algo,
$this->_key,
$encrypted,
MCRYPT_MODE_CBC,
$iv
);
return rtrim($decrypt, "\0");
}
/**
* Encrypt and write the session
*/
public function write($id, $data)
{
$sess_file = $this->_path . $this->_name . "_$id";
$iv = mcrypt_create_iv($this->_ivSize, MCRYPT_DEV_URANDOM);
$encrypted = mcrypt_encrypt(
$this->_algo,
$this->_key,
$data,
MCRYPT_MODE_CBC,
$iv
);
$hmac = hash_hmac('sha256', $iv . $this->_algo . $encrypted, $this->_auth);
$bytes = file_put_contents($sess_file, $hmac . ':' . base64_encode($iv) . ':' . base64_encode($encrypted));
return ($bytes !== false);
}
/**
* Destroy the session
*/
public function destroy($id)
{
$sess_file = $this->_path . $this->_name . "_$id";
setcookie ($this->_keyName, '', time() - 3600);
return(@unlink($sess_file));
}
/**
* Garbage Collector
*/
public function gc($max)
{
foreach (glob($this->_path . $this->_name . '_*') as $filename) {
if (filemtime($filename) + $max < time()) {
@unlink($filename);
}
}
return true;
}
}
SecSessionHandler.php:
<?php
class SecureSessionHandler extends SecSession {
protected $key, $name, $cookie;
public function start()
{
if (session_id() === '') {
if (session_start()) {
return mt_rand(0, 4) === 0 ? $this->refresh() : true; // 1/5
}
}
return false;
}
public function forget()
{
if (session_id() === '') {
return false;
}
$_SESSION = [];
setcookie(
$this->name,
'',
time() - 42000,
$this->cookie['path'],
$this->cookie['domain'],
$this->cookie['secure'],
$this->cookie['httponly']
);
return session_destroy();
}
public function refresh()
{
return session_regenerate_id(true);
}
public function isExpired($ttl = 30)
{
$last = isset($_SESSION['_last_activity'])
? $_SESSION['_last_activity']
: false;
if ($last !== false && time() - $last > $ttl * 60) {
return true;
}
$_SESSION['_last_activity'] = time();
return false;
}
public function isFingerprint()
{
$hash = md5(
$_SERVER['HTTP_USER_AGENT'] .
(ip2long($_SERVER['REMOTE_ADDR']) & ip2long('255.255.0.0'))
);
if (isset($_SESSION['_fingerprint'])) {
return $_SESSION['_fingerprint'] === $hash;
}
$_SESSION['_fingerprint'] = $hash;
return true;
}
public function isValid()
{
return ! $this->isExpired() && $this->isFingerprint();
}
public function get($name)
{
$parsed = explode('.', $name);
$result = $_SESSION;
while ($parsed) {
$next = array_shift($parsed);
if (isset($result[$next])) {
$result = $result[$next];
} else {
return null;
}
}
return $result;
}
public function put($name, $value)
{
$parsed = explode('.', $name);
$session =& $_SESSION;
while (count($parsed) > 1) {
$next = array_shift($parsed);
if ( ! isset($session[$next]) || ! is_array($session[$next])) {
$session[$next] = [];
}
$session =& $session[$next];
}
$session[array_shift($parsed)] = $value;
}
}
$session = new SecureSessionHandler();
ini_set('session.save_handler', 'files');
session_set_save_handler($session, false);
session_save_path(__DIR__ . '\sessions');
$session->start();
if ( ! $session->isValid(5)) {
$session->destroy();
}
$session->put('xxxx', 'xxxxxx');
答案 0 :(得分:1)
您忘了告诉PHP您的SecSession
类实现了接口SessionHandlerInterface
。你可以这样做:
class SecSession implements SessionHandlerInterface {