2023-03-08 17:30:16 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
/**
|
|
|
|
|
|
* SessionMiddleware.php@HDK-Core
|
|
|
|
|
|
*
|
|
|
|
|
|
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
|
|
|
|
|
* Powered by PhpStorm
|
|
|
|
|
|
* Created on 2023/3/8
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
namespace Singularity\HDK\Core\Middleware;
|
|
|
|
|
|
|
|
|
|
|
|
use Carbon\Carbon;
|
|
|
|
|
|
use Hyperf\Contract\ConfigInterface;
|
|
|
|
|
|
use Hyperf\Contract\SessionInterface;
|
|
|
|
|
|
use Hyperf\HttpMessage\Cookie\Cookie;
|
|
|
|
|
|
use Hyperf\HttpMessage\Server\Response;
|
|
|
|
|
|
use Hyperf\Session\SessionManager;
|
2023-07-05 16:40:38 +08:00
|
|
|
|
use Psr\Http\Message\RequestInterface;
|
2023-03-08 17:30:16 +08:00
|
|
|
|
use Psr\Http\Message\ResponseInterface;
|
|
|
|
|
|
use Psr\Http\Message\ServerRequestInterface;
|
2023-07-05 16:40:38 +08:00
|
|
|
|
use Psr\Http\Server\MiddlewareInterface;
|
|
|
|
|
|
use Psr\Http\Server\RequestHandlerInterface;
|
2023-03-08 17:30:16 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Singularity\HDK\Core\Middleware\SessionMiddleware@HDK-Core
|
|
|
|
|
|
*
|
|
|
|
|
|
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
|
|
|
|
|
* Powered by PhpStorm
|
|
|
|
|
|
* Created on 2023/3/8
|
2023-07-05 16:40:38 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @deprecated since 0.2.21, use \Singularity\HDK\Auth\Middleware\SessionMiddleware instead.
|
2023-03-08 17:30:16 +08:00
|
|
|
|
*/
|
2023-07-05 16:40:38 +08:00
|
|
|
|
class SessionMiddleware implements MiddlewareInterface
|
2023-03-08 17:30:16 +08:00
|
|
|
|
{
|
|
|
|
|
|
public function __construct(private SessionManager $sessionManager, private ConfigInterface $config)
|
|
|
|
|
|
{
|
2023-07-05 16:40:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Process an incoming server request.
|
|
|
|
|
|
* Processes an incoming server request in order to produce a response.
|
|
|
|
|
|
* If unable to produce the response itself, it may delegate to the provided
|
|
|
|
|
|
* request handler to do so.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!$this->isSessionAvailable()) {
|
|
|
|
|
|
return $handler->handle($request);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$session = $this->sessionManager->start($request);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
$response = $handler->handle($request);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
$this->storeCurrentUrl($request, $session);
|
|
|
|
|
|
$session = $this->sessionManager->getSession();
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* 现在的机制,但凡写入 Redis 的数据,
|
|
|
|
|
|
* 过期时间就是固定的 gc_maxlifetime
|
|
|
|
|
|
*
|
|
|
|
|
|
* 而 RedisHandler 只会被依赖注入时加载一次,
|
|
|
|
|
|
* 后续无法临时修改 gc_maxlifetime
|
|
|
|
|
|
*
|
|
|
|
|
|
* 又因为现在没有其他情况用到 session
|
|
|
|
|
|
* 只有登录之后才会记下用户信息
|
|
|
|
|
|
*
|
|
|
|
|
|
* 所以一个妥协的方案,就是只有登录了再写入 Redis
|
|
|
|
|
|
*
|
|
|
|
|
|
* (除非重写整套 RedisHandler/RedisHandlerFactory/...)
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (!$this->auth($session)) {
|
|
|
|
|
|
$this->sessionManager->end($session);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $this->addCookieToResponse($request, $response, $session);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function isSessionAvailable(): bool
|
|
|
|
|
|
{
|
|
|
|
|
|
return $this->config->has('session.handler');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Store the current URL for the request if necessary.
|
|
|
|
|
|
*/
|
2023-12-04 17:12:12 +08:00
|
|
|
|
private function storeCurrentUrl(RequestInterface $request, SessionInterface $session): void
|
2023-07-05 16:40:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
if ($request->getMethod() === 'GET') {
|
|
|
|
|
|
$session->setPreviousUrl($this->fullUrl($request));
|
|
|
|
|
|
}
|
2023-03-08 17:30:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Add the session cookie to the response·.
|
|
|
|
|
|
*/
|
|
|
|
|
|
private function addCookieToResponse(
|
|
|
|
|
|
ServerRequestInterface $request,
|
|
|
|
|
|
ResponseInterface $response,
|
|
|
|
|
|
SessionInterface $session
|
|
|
|
|
|
): ResponseInterface {
|
|
|
|
|
|
$cookie = new Cookie(
|
|
|
|
|
|
name: $session->getName(),
|
|
|
|
|
|
value: $session->getId(),
|
2023-07-05 16:40:38 +08:00
|
|
|
|
expire: $this->getCookieExpirationDate($session),
|
2023-03-08 17:30:16 +08:00
|
|
|
|
path: $this->config->get('session.options.path', '/'),
|
|
|
|
|
|
domain: $this->config->get('session.options.domain', $request->getUri()->getHost()),
|
2023-07-05 16:40:38 +08:00
|
|
|
|
secure: $this->config->get(
|
|
|
|
|
|
'session.options.secure',
|
|
|
|
|
|
strtolower($request->getUri()->getScheme()) === 'https'
|
|
|
|
|
|
),
|
2023-03-08 17:30:16 +08:00
|
|
|
|
httpOnly: true,
|
2023-03-08 17:37:27 +08:00
|
|
|
|
sameSite: $this->config->get('session.options.samesite', Cookie::SAMESITE_LAX)
|
2023-03-08 17:30:16 +08:00
|
|
|
|
);
|
|
|
|
|
|
if (!method_exists($response, 'withCookie')) {
|
|
|
|
|
|
return $response->withHeader('Set-Cookie', (string)$cookie);
|
|
|
|
|
|
}
|
|
|
|
|
|
/* @var Response $response */
|
|
|
|
|
|
return $response->withCookie($cookie);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-05 16:40:38 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Get the full URL for the request.
|
|
|
|
|
|
*/
|
|
|
|
|
|
private function fullUrl(RequestInterface $request): string
|
|
|
|
|
|
{
|
|
|
|
|
|
$uri = $request->getUri();
|
|
|
|
|
|
$query = $uri->getQuery();
|
|
|
|
|
|
$question = $uri->getHost() . $uri->getPath() == '/' ? '/?' : '?';
|
|
|
|
|
|
return $query ? $this->url($request) . $question . $query : $this->url($request);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-08 17:30:16 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Get the session lifetime in seconds.
|
|
|
|
|
|
*/
|
2023-07-05 16:40:38 +08:00
|
|
|
|
private function getCookieExpirationDate(SessionInterface $session): int
|
2023-03-08 17:30:16 +08:00
|
|
|
|
{
|
2023-07-05 16:40:38 +08:00
|
|
|
|
// if ($this->config->get('session.options.expire_on_close')) {
|
|
|
|
|
|
if (!$this->auth($session)) {
|
2023-03-08 17:30:16 +08:00
|
|
|
|
$expirationDate = 0;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$expireSeconds = $this->config->get('session.options.cookie_lifetime', 5 * 60 * 60);
|
|
|
|
|
|
$expirationDate = Carbon::now()->addSeconds($expireSeconds)->getTimestamp();
|
|
|
|
|
|
}
|
|
|
|
|
|
return $expirationDate;
|
|
|
|
|
|
}
|
2023-07-05 16:40:38 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Get the URL (no query string) for the request.
|
|
|
|
|
|
*/
|
|
|
|
|
|
private function url(RequestInterface $request): string
|
|
|
|
|
|
{
|
|
|
|
|
|
return rtrim(preg_replace('/\?.*/', '', (string)$request->getUri()));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-04 17:12:12 +08:00
|
|
|
|
private function auth(SessionInterface $session): bool
|
2023-07-05 16:40:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
return $session->has('userInfo');
|
|
|
|
|
|
}
|
2023-03-14 18:29:05 +08:00
|
|
|
|
}
|