facile-it /
php-openid-client
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types=1); |
||
| 4 | |||
| 5 | namespace Facile\OpenIDClient\Middleware; |
||
| 6 | |||
| 7 | use function class_exists; |
||
| 8 | use Dflydev\FigCookies\Cookies; |
||
| 9 | use Dflydev\FigCookies\FigResponseCookies; |
||
| 10 | use Dflydev\FigCookies\Modifier\SameSite; |
||
| 11 | use Dflydev\FigCookies\SetCookie; |
||
| 12 | use Facile\OpenIDClient\Exception\LogicException; |
||
| 13 | use Facile\OpenIDClient\Exception\RuntimeException; |
||
| 14 | use Facile\OpenIDClient\Session\AuthSession; |
||
| 15 | use Facile\OpenIDClient\Session\AuthSessionInterface; |
||
| 16 | use function is_array; |
||
| 17 | use function json_decode; |
||
| 18 | use function json_encode; |
||
| 19 | use Psr\Http\Message\ResponseInterface; |
||
| 20 | use Psr\Http\Message\ServerRequestInterface; |
||
| 21 | use Psr\Http\Server\MiddlewareInterface; |
||
| 22 | use Psr\Http\Server\RequestHandlerInterface; |
||
| 23 | use Psr\SimpleCache\CacheInterface; |
||
| 24 | |||
| 25 | /** |
||
| 26 | * @psalm-import-type AuthSessionType from AuthSessionInterface |
||
| 27 | */ |
||
| 28 | class SessionCookieMiddleware implements MiddlewareInterface |
||
| 29 | { |
||
| 30 | public const SESSION_ATTRIBUTE = AuthSessionInterface::class; |
||
| 31 | |||
| 32 | /** @var string */ |
||
| 33 | private $cookieName; |
||
| 34 | |||
| 35 | /** @var int */ |
||
| 36 | private $ttl; |
||
| 37 | |||
| 38 | /** @var CacheInterface */ |
||
| 39 | private $cache; |
||
| 40 | |||
| 41 | public function __construct(CacheInterface $cache, string $cookieName = 'openid', int $ttl = 300) |
||
| 42 | { |
||
| 43 | $this->cache = $cache; |
||
| 44 | $this->cookieName = $cookieName; |
||
| 45 | $this->ttl = $ttl; |
||
| 46 | } |
||
| 47 | |||
| 48 | public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface |
||
| 49 | { |
||
| 50 | if (! class_exists(Cookies::class)) { |
||
| 51 | throw new LogicException('To use the SessionCookieMiddleware you should install dflydev/fig-cookies package'); |
||
| 52 | } |
||
| 53 | |||
| 54 | $cookies = Cookies::fromRequest($request); |
||
| 55 | $sessionCookie = $cookies->get($this->cookieName); |
||
| 56 | |||
| 57 | $sessionId = null !== $sessionCookie ? $sessionCookie->getValue() : null; |
||
| 58 | /** @var string|null $sessionValue */ |
||
| 59 | $sessionValue = null !== $sessionId ? $this->cache->get($sessionId) : null; |
||
| 60 | /** @var false|AuthSessionType $data */ |
||
| 61 | $data = null !== $sessionValue ? json_decode($sessionValue, true) : []; |
||
| 62 | |||
| 63 | if (! is_array($data)) { |
||
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
| 64 | $data = []; |
||
| 65 | } |
||
| 66 | |||
| 67 | $authSession = AuthSession::fromArray($data); |
||
| 68 | |||
| 69 | $response = $handler->handle($request->withAttribute(self::SESSION_ATTRIBUTE, $authSession)); |
||
| 70 | |||
| 71 | $sessionId = $sessionId ?? bin2hex(random_bytes(32)); |
||
| 72 | |||
| 73 | /** @var string $sessionValue */ |
||
| 74 | $sessionValue = json_encode($authSession); |
||
| 75 | |||
| 76 | if (false === $this->cache->set($sessionId, $sessionValue, $this->ttl)) { |
||
| 77 | throw new RuntimeException('Unable to save session'); |
||
| 78 | } |
||
| 79 | |||
| 80 | $sessionCookie = SetCookie::create($this->cookieName) |
||
| 81 | ->withValue($sessionId) |
||
| 82 | ->withMaxAge($this->ttl) |
||
| 83 | ->withHttpOnly() |
||
| 84 | ->withPath('/') |
||
| 85 | ->withSameSite(SameSite::strict()); |
||
| 86 | |||
| 87 | $response = FigResponseCookies::set($response, $sessionCookie); |
||
| 88 | |||
| 89 | return $response; |
||
| 90 | } |
||
| 91 | } |
||
| 92 |