未捕获Slim\Exception\HttpMethodNotAllowedException:不允许的方法。必须是以下之一:GET

Uncaught Slim\Exception\HttpMethodNotAllowedException: Method not allowed. Must be one of: GET

我正在尝试在我的 chrome 扩展和我的 slim php REST API 中实施 firebase 身份验证。在使用扩展清单和 php 服务器代码进行一些配置后,我遇到了令牌验证问题。当我尝试传递从 chrome.identity.getAuthToken():

获得的令牌时,我总是会收到此错误
PHP Fatal error:  Uncaught Slim\Exception\HttpMethodNotAllowedException: Method not allowed. Must be one of: GET

问题是我在客户端使用 get 方法。我的 axios 代码是这样的:

      axios.get('http://localhost:3000/keygen', {
        headers: {
          'Authorization': `Bearer ${this.authToken}`
        }
      })
      .then( (response) => {
        console.log(response, response.data);
        this.password = response.data.generated_password;
        this.createdPassword = response.data.generated_password;
      });

在服务器端我有这个代码:

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;


require_once __DIR__.'/vendor/autoload.php';

//I'm adding headers because I'm on localhost and I have a CORS error if I don't specify the chrome ectension id from witch the requests come from. This problem will not occur on live server
header("Access-Control-Allow-Origin: chrome-extension://oegddbimpfdpbojkmfibkebnagidflfc");
header("Access-Control-Allow-Methods: GET, POST");
header("Access-Control-Allow-Headers: Authorization");
header("Access-Control-Allow-Credentials: true");

require_once __DIR__.'/vendor/autoload.php';

$app = AppFactory::create();

$rawPublicKeys = file_get_contents('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com');
$keys = json_decode($rawPublicKeys, true);

$app->add(new Tuupola\Middleware\JwtAuthentication([
    //"ignore" => [""]
    "secret" => $keys,
    "header" => "X-Authorization",
    "regexp" => "/Bearer\s+(.*)$/i",
    "algorithm" => ["RS256"],
]));

$app->get('/keygen', function(Request $request, Response $response, $args){  
    $password = bin2hex(random_bytes(3));
    $response->getBody()->write( json_encode(['generated_password' => $password]) );
    return $response->withHeader('Content-Type','application/json');
});

我该如何解决这个问题?在让用户能够向我的 api 端点发出请求之前,我想使用 firebase 和身份 api 对用户进行身份验证。感谢您的帮助。

编辑

我已经按照 slim 提供的文档修改了 php 代码,现在这个问题似乎已解决,但我收到 401 错误。我会 post 这个问题的另一个问题

新代码

$app->options('/{routes:.+}', function ($request, $response, $args) {
    return $response;
});

$app->add(function ($request, $handler) {
    $response = $handler->handle($request);
    return $response
            ->withHeader('Access-Control-Allow-Origin', 'chrome-extension://oegddbimpfdpbojkmfibkebnagidflfc')
            ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
            ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
});

$rawPublicKeys = file_get_contents('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com');
$keys = json_decode($rawPublicKeys, true);

$app->add(new Tuupola\Middleware\JwtAuthentication([
    //"ignore" => [""]
    "secret" => $keys,
    "header" => "X-Authorization",
    "regexp" => "/Bearer\s+(.*)$/i",
    "algorithm" => ["RS256"],
]));

$app->get('/keygen', function(Request $request, Response $response, $args){  
    $password = bin2hex(random_bytes(3));
    $response->getBody()->write( json_encode(['generated_password' => $password]) );
    return $response->withHeader('Content-Type','application/json');
});

$app->map(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], '/{routes:.+}', function ($request, $response) {
    throw new HttpNotFoundException($request);
});

肯定是任何请求的指定路由已经被指定为GET,但你可能是用其他方法而不是GET,请检查一次是否有任何时候Route不匹配。

对于替代解决方案,您还可以将路线提及为 any,如:

Route::any('/', 'PagesController@index');

问题是由开发期间从本地主机发出的 OPTIONS 请求引起的。由于我没有配置任何端点来接受 OPTIONS 请求,我已经使用管理 CORS 的中间件解决了这个问题。