首页 > 解决方案 > 未捕获的 Slim\Exception\HttpMethodNotAllowedException:方法不允许。必须是以下之一:GET

问题描述

我正在尝试在我的 chrome 扩展和我的超薄 php REST API 中实现 firebase auth。在使用扩展清单和 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 endopints 发出请求之前,我想使用 firebase 和 identity api 对用户进行身份验证。谢谢您的帮助。

编辑

我已经按照 slim 提供的文档修改了 php 代码,现在这个问题似乎已解决,但出现 401 错误。我将针对此问题发布另一个问题

新代码

$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);
});

标签: phpfirebase-authenticationaxioshttp-headersslim

解决方案


它必须是已分配为 GET 的任何请求的分配路由,但您可能会使用其他方法而不是 GET,请检查一次路由中是否存在不匹配的时间。

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

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

推荐阅读