提问人: 提问时间:4/20/2019 更新时间:11/18/2023 访问量:8947
GuzzleHTTP 在现有页面上返回 404
GuzzleHTTP returns 404 on existing page
问:
我对 https://api.scarif.dev/auth 的 Guzzle POST 请求返回了 404,而该页面通过 Postman、浏览器或 javascript 存在。它应该返回带有 401 消息的 200,但 Guzzle 返回 404。在 POST 和 GET 模式下都是如此。
我尝试了多种客户端设置,包括不同的标头和禁用 SSL 验证,但没有成功。现在我已经复制了使其在 postman 中工作的完全相同的标题,但仍然没有成功。
我一直在搜索谷歌和stackoverflow,但找不到解决我问题的答案。
PHP中的请求:
<?php
$client = new Client([
'header' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded'
],
'verify' => false
]);
$response = $client->request('POST', 'https://api.scarif.dev/auth', [
'form_params' => []
]);
echo $response->getBody()->getContents();
?>
预期结果:
{
"detail": "https://login.scarif.dev",
"status": 401,
"title": "Unauthorized",
"type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"
}
实际结果:
致命错误:未捕获的 GuzzleHttp\Exception\ClientException:客户端 错误:导致响应: 404 未找到
POST https://api.scarif.dev/auth
404 Not Found
未找到 (截断...) 在 /home/admin/domains/login.scarif.dev/framework/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113 堆栈跟踪:#0 /home/admin/domains/login.scarif.dev/framework/vendor/guzzlehttp/guzzle/src/Middleware.php(66): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), 对象 (GuzzleHttp\Psr7\Response)) #1 /home/admin/domains/login.scarif.dev/framework/vendor/guzzlehttp/promises/src/Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp{closure}(Object(GuzzleHttp\Psr7\Response)) 2 /home/admin/domains/login.scarif.dev/framework/vendor/guzzlehttp/promises/src/Promise.php(156):
GuzzleHttp\Promise\Promise::callHandler(1, 对象 (GuzzleHttp\Psr7\Response), 数组) #3 /home/admin/domains/login.scarif.dev/framework/ven 中 /home/admin/domains/login.scarif.dev/framework/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php 上线 113
API 端点控制器:
<?php
namespace Controller;
use Core\Config;
use Core\Request;
use Core\Response;
use Model\Token;
use Model\User;
use MongoDB\BSON\UTCDateTime;
class AuthController extends Controller
{
public function view(User $user, Token $token)
{
extract(Request::getPostData());
if (isset($access_token) && !empty($access_token)) {
$_token = $token->getTokenByToken($access_token);
if (
$_token['type'] !== Token::TYPE_ACCESS_TOKEN ||
$_token['expires_on'] <= new UTCDateTime()
) {
return $this->view->display('json', [
'payload' => Response::apiResponse(
$this->config->get('url.login'), 401
)
]);
}
$token->delete($_token['_id']);
$newToken = $token->create(Token::TYPE_ACCESS_TOKEN, $_token['user_id']);
return $this->view->display('json', [
'payload' => Response::apiResponse($newToken['token'])
]);
}
if (!isset($email) || !isset($password) || empty($email) || empty($password)) {
return $this->view->display('json', [
'payload' => Response::apiResponse(
$this->config->get('url.login'), 401
)
]);
}
if (!$user->checkCredentials($email, $password)) {
return $this->view->display('json', [
'payload' => Response::apiResponse(
"The email address or password you've entered is invalid. Please check your entry and try again.",
422
)
]);
}
$user = $user->getUserByEmail($email);
$token = $token->create(Token::TYPE_ACCESS_TOKEN, $user['_id']);
return $this->view->display('json', [
'payload' => Response::apiResponse($token['token'])
]);
}
}
答:
问题似乎来自您正在使用的 API。当将代码与不同的 url 一起使用时,它工作得很好:
$client = new Client([
'header' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded'
],
'verify' => false
]);
$response = $client->request('POST', 'https://jsonplaceholder.typicode.com/posts', [
'form_params' => []
]);
echo $response->getBody()->getContents();
您能展示 API 端点的代码吗?
评论
我遇到了同样的问题,一直在寻找解决方案,直到我来到这里。虽然没有在网上得到任何帮助,其他人的解决方案对我不起作用,但后来我通过广泛的调试解决了自己,我正在分享解决方案,希望将来可以帮助其他人。
场景:在我的例子中,我有一个 API 网关,客户端(在我的情况下是 Postman)正在向 API 网关发出请求,网关又在 Laravel 8 中使用 Guzzle 7 向微服务发出请求。我曾经将我从客户端收到的所有标头按原样传递到微服务,这导致了 404 错误。当我更改它并仅将请求中我自己的标头传递给微服务时,出现了光,404 消失了。
这些是 Postman 的默认标头,我按原样传递请求:
{
"authorization": [
"Bearer eyJ0eXAiOiJKV1 .."
],
"user-agent": [
"PostmanRuntime/7.29.0"
],
"accept": [
"*/*"
],
"postman-token": [
"ca180f3a-ec65-4212-bd9f-dc294846dc65"
],
"host": [
"sagateway.com"
],
"accept-encoding": [
"gzip, deflate, br"
],
"connection": [
"keep-alive"
]
}
我删除了所有这些内容,只在标题中传递了一件事:
['Authorization' => "<Key Here>"]
然后它工作正常,经过几天的连续谷歌搜索,我松了一口气。
评论