I am creating a REST API using CI4. I want to create a auth filter and ran into a problem.
When token is valid or not send, everything is fine.
Problem is when I change the content of token before sending (add or remove a character) then instead of getting response that is in catch I have this in Chrome console:
GET https://api.***/admin/users 500
<br />
<b>Fatal error</b>: Uncaught CodeIgniter\Format\Exceptions\FormatException: Failed to parse json string, error: "Malformed UTF-8 characters, possibly incorrectly encoded". in /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/Format/JSONFormatter.php:41
Stack trace:
#0 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/Format/JSONFormatter.php(41): CodeIgniter\Format\Exceptions\FormatException::forInvalidJSON('Malformed UTF-8...')
#1 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/API/ResponseTrait.php(341): CodeIgniter\Format\JSONFormatter->format(Array)
#2 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/API/ResponseTrait.php(99): CodeIgniter\Debug\Exceptions->format(Array)
#3 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/Debug/Exceptions.php(115): CodeIgniter\Debug\Exceptions->respond(Array, 500)
#4 [internal function]: CodeIgniter\Debug\Exceptions->exceptionHandler(Object(DomainException))
#5 in <b>/home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/Format/JSONFormatter.php</b> on line <b>41</b><br />
{
"title": "ErrorException",
"type": "ErrorException",
"code": 500,
"message": "Uncaught CodeIgniter\\Format\\Exceptions\\FormatException: Failed to parse json string, error: \"Malformed UTF-8 characters, possibly incorrectly encoded\". in /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/Format/JSONFormatter.php:41\nStack trace:\n#0 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/Format/JSONFormatter.php(41): CodeIgniter\\Format\\Exceptions\\FormatException::forInvalidJSON('Malformed UTF-8...')\n#1 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/API/ResponseTrait.php(341): CodeIgniter\\Format\\JSONFormatter->format(Array)\n#2 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/API/ResponseTrait.php(99): CodeIgniter\\Debug\\Exceptions->format(Array)\n#3 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/Debug/Exceptions.php(115): CodeIgniter\\Debug\\Exceptions->respond(Array, 500)\n#4 [internal function]: CodeIgniter\\Debug\\Exceptions->exceptionHandler(Object(DomainException))\n#5",
"file": "/home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/Format/JSONFormatter.php",
"line": 41,
"trace": [
{
"function": "shutdownHandler",
"class": "CodeIgniter\\Debug\\Exceptions",
"type": "->",
"args": []
}
]
}
app/Filters/Auth.php:
<?php
namespace App\Filters;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class Auth implements FilterInterface {
public function before(RequestInterface $request, $arguments = null) {
$key = getenv('JWT_SECRET');
$header = $request->getServer('HTTP_AUTHORIZATION');
$token = null;
if (!empty($header)) {
$token = explode(' ', $header)[1];
}
if (is_null($token) || empty($token)) {
$response = [
'status' => 401,
'error' => true,
'message' => 'Token required.',
'data' => []
];
echo json_encode($response);
exit();
}
try {
JWT::decode($token, new Key($key, 'HS256'));
} catch (Exception $ex) {
$response = [
'status' => 401,
'error' => true,
'message' => 'Access denied.',
'data' => []
];
echo json_encode($response);
exit();
}
}
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) {
//
}
}
How do I get response I created?
This is all about namespaces.
When your file begins with a namespace
declaration, every bare class name in the file is compiled as though that namespace was on the front of its name, unless one of two things applies:
\
, meaning it is a "Fully-Qualified Class Name" ("FQCN")use
statement, meaning it will be substituted with that class name insteadSo, when the compiler sees this line:
} catch (Exception $ex) {
It is compiling it as though you wrote this:
} catch (\App\Filters\Exception $ex) {
But what you intended was the built-in class Exception
, which is the base class for all user-land exceptions. As an FQCN, that would be written like this:
} catch (\Exception $ex) {
Or you could add a use
statement for it, such as this:
use Exception;
Of course, if you wanted to handle this specific exception, you would instead write this:
} catch (\CodeIgniter\Format\Exceptions\FormatException $ex) {
Or more likely this:
// near top of file
use CodeIgniter\Format\Exceptions\FormatException;
// ... many lines later ...
} catch (FormatException $ex) {