juliangut / sessionware
PSR7 会话管理中间件
Requires
- php: >=5.5
- league/event: ^2.1
- psr/http-message: ^1.0
- symfony/polyfill-php56: ^1.0
- symfony/polyfill-php70: ^1.0
Requires (Dev)
- phpmd/phpmd: ^2.2
- phpunit/phpunit: ^4.5|^5.0
- sebastian/phpcpd: ^2.0
- sensiolabs/security-checker: ^3.0
- squizlabs/php_codesniffer: ^2.0
- zendframework/zend-diactoros: ^1.3
README
SessionWare
一个 PSR7 会话管理中间件。
自动控制会话超时。
使用 random_bytes
生成一个 80 字符长的会话 ID,这是一个真正的密码学安全的伪随机生成器,而不是使用 session.hash_function
哈希算法。
重要注意事项
请注意,此中间件需要一些会话 ini
设置为特定值
session.use_trans_sid
设置为 false
,session.use_cookies
设置为 true
,session.use_only_cookies
设置为 true
,session.use_strict_mode
设置为 false
,session.cache_limiter
设置为空字符串(空字符串)
这些值将防止会话头自动发送给用户。 将相应的缓存头包含在响应对象中是开发者的责任,这应该是首选做法,而不是依赖 PHP 环境设置。
您可以使用 juliangut/cacheware,它将自动设置正确的会话 ini 设置,并将相应的缓存头添加到响应对象中。
在执行期间使用 session_regenerate_id()
时,密码学安全的会话 ID 将默认由 PHP 的 session.hash_function
生成的 ID 替换(并不真正安全)。为了防止这种情况发生,请使用 \Jgut\Middleware\Session
辅助方法的 regenerateSessionId()
代替
\Jgut\Middleware\Session::regenerateSessionId();
安装
Composer
composer require juliangut/sessionware
用法
require 'vendor/autoload.php'; use \Jgut\Middleware\SessionWare $configuration = [ 'name' => 'myProjectSessionName', 'lifetime' => 1800, // 30 minutes ]; $sessionMiddleware = new SessionWare($configuration); // Get $request and $response from PSR7 implementation $request = new Request(); $response = new Response(); $response = $sessionMiddleware($request, $response, function() { }); // Session is started, populated with default parameters and response has session cookie header
集成在中间件工作流程中
require 'vendor/autoload.php'; use \Jgut\Middleware\SessionWare $configuration = [ 'name' => 'myProjectSessionName', 'lifetime' => SessionWare::SESSION_LIFETIME_NORMAL, // 15 minutes ]; $defaultSessionParams = [ 'default_timezone' => 'UTC', ] $app = new \YourMiddlewareAwareApplication(); $app->addMiddleware(new SessionWare($configuration, $defaultParameters)); $app->run();
会话助手
有一个额外的会话助手来抽象访问 $_SESSION 变量。这对于例如当不访问全局变量很重要时很有用(例如,当使用 PHP_MD 对您的代码进行静态分析时)
要利用 SessionWare 生成的密码学安全的会话 ID,请务必使用
$session = new \Jgut\Middleware\Session;
$session->regenerate();
// Or can be called statically
\Jgut\Middleware\Session::regenerateSessionId()
配置
$sessionMiddleware = new SessionWare([ 'timeoutKey' => '__SESSIONWARE_TIMEOUT_TIMESTAMP__' 'name' => 'SessionWareSession', 'savePath' => '/tmp/SessionWareSession', 'lifetime' => SessionWare::SESSION_LIFETIME_NORMAL, 'domain' => 'http://example.com', 'path' => '/', 'secure' => false, 'httponly' => true, ]);
默认值模仿默认 PHP 安装提供的值,以便中间件可以直接作为直接替换使用,并自动控制会话超时
timeoutKey
存储在会话数组中的参数,根据 lifetime
参数控制会话的有效性。默认值为
\Jgut\Middleware\SessionWare::SESSION_TIMEOUT_KEY_DEFAULT = '__SESSIONWARE_TIMEOUT_TIMESTAMP__';
建议不要更改此值,除非它与您的某个自己的会话键冲突(如果不直接不可能,则不太可能发生)
name
分配会话名称,如果没有提供,则将使用默认的 PHP PHPSESSID
会话名称。
请参阅以下重要说明。
savePath
此配置仅在默认的 'files' 会话保存处理程序在 session.save_handler
中选择时使用。
分配用于存储会话文件的路径。如果没有提供,则将使用 sys_get_temp_dir()
、session_save_path()
和会话 'name' 来组成一个唯一的路径。
请参阅以下重要说明。
lifetime
会话被认为是有效的时间(秒数)。如果没有提供,则使用 session.gc_maxlifetime
和 session.cookie_lifetime
来发现 PHP 配置的会话生命周期。最后,如果没有提供或其值为零,则默认为 SessionWare::SESSION_LIFETIME_DEFAULT
(24分钟)。
有六个会话生命周期常量可供方便使用
- SESSION_LIFETIME_FLASH = 5 分钟
- SESSION_LIFETIME_SHORT = 10 分钟
- SESSION_LIFETIME_NORMAL = 15 分钟
- SESSION_LIFETIME_DEFAULT = 24 分钟
- SESSION_LIFETIME_EXTENDED = 1 小时
- SESSION_LIFETIME_INFINITE =
PHP_INT_MAX
,在 x86_64 架构上约为 1145 年
path, domain, secure and httponly
到 session.cookie_path
、session.cookie_domain
、session.cookie_secure
和 session.cookie_httponly
的快捷方式。如果没有提供,则使用配置的 cookie 参数,因此可以在中间件运行之前使用 session_set_cookie_params()
设置。
事件
您可以通过监听超时事件来执行相应的操作。目前有两个事件
pre.session_timeout
在达到会话超时时,会在会话被清除之前触发post.session_timeout
在会话由于超时而重启后立即触发
事件提供sessionId作为参数
$sessionware = new SessionWare($configuration); $sessionware->addListener('pre.session_timeout', function($sessionId) { echo sprintf('session "%s" timed out', $sessionId); }) $sessionware->addListener('post.session_timeout', function($sessionId) { echo sprintf('new session "%s" created', $sessionId); })
重要提示
使用默认的 'files' 会话保存处理器
如果您定义了会话 'lifetime',您 必须 设置会话 'savePath' 或会话 'name'(不同于 PHPSESSID
)。这是为了将会话文件与其他PHP脚本的会话文件分开,以便垃圾回收器正确处理过期文件的删除。
请注意,如果这个条件不满足,启动会话可能会删除其他脚本/应用程序的会话文件,因为它们都位于同一个目录中,并且垃圾回收器无法知道它们属于哪个脚本/应用程序。
使用自定义会话保存处理器
在这种情况下,区分不同的脚本/应用程序会话文件不应该有问题。但请注意,不要直接将cookie头(setcookie
)发送到客户端,而是将它们包含在响应对象中。
在运行此中间件之前注册您的自定义会话保存处理器,以防止创建savePath。
贡献
发现了错误或有功能请求? 请创建一个新问题。在提交之前,请查看现有的问题。
见文件 CONTRIBUTING.md
许可证
有关许可证条款的副本,请参阅源代码中包含的文件 LICENSE。