This example extends the Login-example, by:
LoginResponseHandler which sets cookies
andThis example is not meant to show a security feature, but is meant to show soem basic handling of cookies using giwt.
The new LoginResponseHandler sets cookies once the user was authenticated.
<?php
namespace Graphit\Examples;
class LoginResponseHandler implements \Graphit\Core\ResponseHandlerInterface
{
public function __construct(\Graphit\Core\Kernel $kernel)
{
$this->kernel = $kernel;
}
public function handleResponse(\Graphit\Core\Response $response, \Graphit\Core\Request $request)
{
$authenticated = $this->kernel['authenticated'];
if (!$authenticated) {
return $response;
}
$secret = $this->kernel['cookie'][$authenticated];
$cookies = [
'login' => ['value' => $authenticated, 'expire' => time() + (24 * 60 * 60 * 20)], // 30 days
'secret' => ['value' => $secret, 'expire' => time() + (24 * 60 * 60 * 20)] // 30 days
];
return $response->setCookies($cookies);
}
}
In case the user wasn't authenticated, no cookies will be set. On the other hand if the user was successfully authenticated a 'login'- and a 'secret'-cookie are set.
So since future request might contain our cookies we need to adjust our LoginRequestHandler-class.
Inside the LoginRequestHandler we adjust the handleRequest-method to not ask for credentials when the incoming request contains valid cookies. (Username and secret match the expected values.)
public function handleRequest(\Graphit\Core\Request $request)
{
$cookie = $request->cookie();
if($cookie && isset($cookie['login']) && isset($cookie['secret'])) {
$username = $cookie['login'];
if ($this->kernel['cookie'][$username] == $cookie['secret']) {
$request->vars()->set('authenticated', $username);
return;
}
}
$username = $request->getUser();
$password = $request->getPassword();
$validator = new LoginValidator($this->kernel);
if ($validator->validate($username, $password)) {
$request->vars()->set('authenticated', $username);
} else {
return $this->requestCredentials($request);
}
}
Next, we adjust the HelloRequestHandler to use the new LoginResponseHandler.
Inside the HelloRequestHandler we add the LoginResponseHandler to the ChainRequestHandler.
public function __construct(\Graphit\Core\Kernel $kernel)
{
$this->kernel = $kernel;
$this->handler = new \Graphit\Core\ChainRequestHandler();
$default = $kernel['defaultLocale'] ?: 'de';
$possible = $kernel['possibleLocales'] ?: ['de'];
$handler = new \Graphit\Core\LocaleRequestHandler($default, $possible);
$this->handler->addRequestHandler($handler);
$router = $kernel['router'];
$handler = new \Graphit\Core\RouterRequestHandler($router);
$this->handler->addRequestHandler($handler);
$handler = new \Graphit\Core\PossibleLocaleRequestHandler();
$this->handler->addRequestHandler($handler);
$handler = new LoginRequestHandler($kernel);
$this->handler->addRequestHandler($handler);
$handler = new \Graphit\Core\ControllerRequestHandler($kernel);
$this->handler->addRequestHandler($handler);
$handler = new LoginResponseHandler($kernel);
$this->handler->addResponseHandler($handler);
}
Since we write cookies which contain a secret and also check for this secret inside the LoginRequestHandler, we now adjust the service.json to hold those secrets. Normally one would read these from a Database or another trusted source, but for this example we keep it minimal.
We just add a "cookie"-array at the top of the to the services.json which holds the 'secret' we expect as cookie for a specific user.
"cookie": {
"username": "a secret",
"test": "secret"
},