세션 처리 SessionHandler 클래스
(PHP 5 >= 5.4.0, PHP 7, PHP 8)
소개
SessionHandler는 상속을 통해 현재 내부 PHP 세션 저장 핸들러를 노출하는 데 사용할 수 있는 특수 클래스입니다. 7개의 내부 세션 저장 핸들러 콜백(open
, close
, read
, write
, destroy
, gc
및 create_sid
)을 래핑하는 7개의 메소드가 있습니다. 기본적으로 이 클래스는 일반적으로 기본적으로 files
인 session.save_handler 구성 지시문에 의해 정의된 대로 내부 저장 핸들러가 설정되는 모든 것을 래핑합니다. 다른 내부 세션 저장 핸들러는 SQLite(sqlite
), Memcache(memcache
) 및 Memcached(memcached
)와 같은 PHP 확장에서 제공됩니다.
SessionHandler의 일반 인스턴스가 session_set_save_handler()를 사용하여 저장 핸들러로 설정되면 현재 저장 핸들러를 래핑합니다. SessionHandler에서 확장된 클래스를 사용하면 메서드를 재정의하거나 궁극적으로 내부 PHP 세션 핸들러를 래핑하는 상위 클래스 메서드를 호출하여 메서드를 가로채거나 필터링할 수 있습니다.
이를 통해 예를 들어 read
및 write
메서드를 가로채서 세션 데이터를 암호화/복호화한 다음 부모 클래스와 결과를 주고받을 수 있습니다. 또는 가비지 컬렉션 콜백 gc
와 같은 메서드를 완전히 재정의하도록 선택할 수도 있습니다.
SessionHandler는 현재 내부 저장 핸들러 메소드를 래핑하기 때문에 위의 암호화 예제는 핸들러의 내부를 몰라도 모든 내부 저장 핸들러에 적용할 수 있습니다.
이 클래스를 사용하려면 먼저 session.save_handler를 사용하여 노출하려는 저장 핸들러를 설정한 다음 SessionHandler 또는 이를 확장하는 인스턴스를 session_set_save_handler()로 전달합니다.
이 클래스의 콜백 메서드는 PHP에서 내부적으로 호출하도록 설계되었으며 사용자 공간 코드에서 호출할 수 없습니다. 반환 값은 PHP에서 내부적으로 동일하게 처리됩니다. 세션 워크플로에 대한 자세한 내용은 session_set_save_handler()를 참조하십시오.
클래스 개요
class SessionHandler implements SessionHandlerInterface, SessionIdInterface {
/* Methods */
public close(): bool
public create_sid(): string
public destroy(string $id): bool
public gc(int $max_lifetime): int|false
public open(string $path, string $name): bool
public read(string $id): string|false
public write(string $id, string $data): bool
}
경고 이 클래스는 현재 내부 PHP 세션 저장 핸들러를 노출하도록 설계되었습니다. 사용자 정의 저장 핸들러를 작성하려면 SessionHandler에서 확장하는 대신 SessionHandlerInterface 인터페이스를 구현하십시오.
예제 #1 SessionHandler를 사용하여 내부 PHP 저장 핸들러에 암호화를 추가합니다.
<?php
/**
* decrypt AES 256
*
* @param data $edata
* @param string $password
* @return decrypted data
*/
function decrypt($edata, $password) {
$data = base64_decode($edata);
$salt = substr($data, 0, 16);
$ct = substr($data, 16);
$rounds = 3; // depends on key length
$data00 = $password.$salt;
$hash = array();
$hash[0] = hash('sha256', $data00, true);
$result = $hash[0];
for ($i = 1; $i < $rounds; $i++) {
$hash[$i] = hash('sha256', $hash[$i - 1].$data00, true);
$result .= $hash[$i];
}
$key = substr($result, 0, 32);
$iv = substr($result, 32,16);
return openssl_decrypt($ct, 'AES-256-CBC', $key, true, $iv);
}
/**
* crypt AES 256
*
* @param data $data
* @param string $password
* @return base64 encrypted data
*/
function encrypt($data, $password) {
// Set a random salt
$salt = openssl_random_pseudo_bytes(16);
$salted = '';
$dx = '';
// Salt the key(32) and iv(16) = 48
while (strlen($salted) < 48) {
$dx = hash('sha256', $dx.$password.$salt, true);
$salted .= $dx;
}
$key = substr($salted, 0, 32);
$iv = substr($salted, 32,16);
$encrypted_data = openssl_encrypt($data, 'AES-256-CBC', $key, true, $iv);
return base64_encode($salt . $encrypted_data);
}
class EncryptedSessionHandler extends SessionHandler
{
private $key;
public function __construct($key)
{
$this->key = $key;
}
public function read($id)
{
$data = parent::read($id);
if (!$data) {
return "";
} else {
return decrypt($data, $this->key);
}
}
public function write($id, $data)
{
$data = encrypt($data, $this->key);
return parent::write($id, $data);
}
}
// we'll intercept the native 'files' handler, but will equally work
// with other internal native handlers like 'sqlite', 'memcache' or 'memcached'
// which are provided by PHP extensions.
ini_set('session.save_handler', 'files');
$key = 'secret_string';
$handler = new EncryptedSessionHandler($key);
session_set_save_handler($handler, true);
session_start();
// proceed to set and retrieve values by key from $_SESSION
이 클래스의 메서드는 일반 세션 워크플로의 일부로 PHP에서 내부적으로 호출하도록 설계되었으므로 세션이 실제로 시작되지 않은 경우(자동으로 또는 명시적 session_start()에 의해) 부모 메서드(즉, 실제 내부 네이티브 핸들러)에 대한 자식 클래스 호출은 false
를 반환합니다. 이것은 클래스 메소드가 수동으로 호출될 수 있는 단위 테스트를 작성할 때 고려하는 것이 중요합니다.
목차
- SessionHandler::close — 세션 닫기
- SessionHandler::create_sid — 새 세션 ID 반환
- SessionHandler::destroy — 세션 파괴
- SessionHandler::gc — 오래된 세션 정리
- SessionHandler::open — 세션 초기화
- SessionHandler::read — 세션 데이터 읽기
- SessionHandler::write — 세션 데이터 쓰기