Added CSRF check in weatherdata API

This commit is contained in:
Dale Davies
2022-04-13 16:28:12 +01:00
parent ad3de9cd27
commit 490758bae8
13 changed files with 86 additions and 17 deletions

View File

@@ -12,6 +12,31 @@ require __DIR__ .'/../vendor/autoload.php';
$config = new Jump\Config();
$cache = new Jump\Cache($config);
// Output header here so we can return early with a json response if there is a curl error.
header('Content-Type: application/json; charset=utf-8');
// Initialise a new session using the request object.
$session = new \Nette\Http\Session((new \Nette\Http\RequestFactory)->fromGlobals(), new \Nette\Http\Response);
$session->setName($config->get('sessionname'));
$session->setExpiration($config->get('sessiontimeout'));
// Get a Nette session section for CSRF data.
$csrfsection = $session->getSection('csrf');
// Has a CSRF token been set up for the session yet?
if (!$csrfsection->offsetExists('token')){
http_response_code(401);
die(json_encode(['error' => 'Session not fully set up']));
}
// Check CSRF token saved in session against token provided via request.
$token = isset($_GET['token']) ? $_GET['token'] : false;
if (!$token || !hash_equals($csrfsection->get('token'), $token)) {
http_response_code(401);
die(json_encode(['error' => 'API token is incorrect or missing']));
}
// Start of variables we want to use.
$owmapiurlbase = 'https://api.openweathermap.org/data/2.5/weather';
$units = $config->parse_bool($config->get('metrictemp')) ? 'metric' : 'imperial';
@@ -35,9 +60,6 @@ $url = $owmapiurlbase
.'&lon=' . $latlong[1]
.'&appid=' . $config->get('owmapikey', false);
// Output header here so we can return early with a json response if there is a curl error.
header('Content-Type: application/json; charset=utf-8');
// Use the cache to store/retrieve data, make an md5 hash of latlong so it is not possible
// to track location history form the stored cache.
$weatherdata = $cache->load(cachename: 'weatherdata', key: md5(json_encode($latlong)), callback: function() use ($url) {
@@ -56,10 +78,11 @@ $weatherdata = $cache->load(cachename: 'weatherdata', key: md5(json_encode($latl
curl_close($ch);
// If we had an error then return the error message and exit, otherwise return the API response.
if (isset($curlerror)) {
http_response_code(400);
die(json_encode(['error' => $curlerror]));
}
return $response;
});
// We made it here so output the API response as json.
echo $weatherdata;
echo $weatherdata;