无效令牌和 'Failed to parse json string'

Invalid token and 'Failed to parse json string'

我正在使用 CI4 创建 REST API。我想创建一个 auth 过滤器并 运行 成问题。

当令牌有效或未发送时,一切正常。

问题是当我在发送之前更改令牌的内容(添加或删除一个字符)然后我没有得到捕获中的响应我在 Chrome 控制台中有这个:

GET https://api.***/admin/users 500

<br />
<b>Fatal error</b>:  Uncaught CodeIgniter\Format\Exceptions\FormatException: Failed to parse json string, error: &quot;Malformed UTF-8 characters, possibly incorrectly encoded&quot;. 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-&gt;format(Array)
#2 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/API/ResponseTrait.php(99): CodeIgniter\Debug\Exceptions-&gt;format(Array)
#3 /home/mma/domains/***/ci4/vendor/codeigniter4/framework/system/Debug/Exceptions.php(115): CodeIgniter\Debug\Exceptions-&gt;respond(Array, 500)
#4 [internal function]: CodeIgniter\Debug\Exceptions-&gt;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) {
        //
    }

}

如何获得我创建的回复?

这都是关于 namespaces

当您的文件以 namespace 声明开头时,文件中的 每个 裸 class 名称都会被编译,就好像该名称空间位于它的名称,除非满足以下两个条件之一:

  • 它以\开头,表示它是一个“Fully-Qualified Class名称”(“FQCN”)
  • 它匹配 use 语句,这意味着它将被 class 名称替代

因此,当编译器看到这一行时:

} catch (Exception $ex) {

编译它就像你这样写:

} catch (\App\Filters\Exception $ex) {

但您想要的是 built-in class Exception,它是所有 user-land 异常的基础 class。作为 FQCN,可以这样写:

} catch (\Exception $ex) {

或者您可以为其添加 use 语句,例如:

use Exception;

当然,如果您想处理这个特定的异常,您应该这样写:

} catch (\CodeIgniter\Format\Exceptions\FormatException $ex) {

或者更可能是:

// near top of file
use CodeIgniter\Format\Exceptions\FormatException;
// ... many lines later ...
} catch (FormatException $ex) {