【问题标题】:GuzzleHTTP returns 404 on existing pageGuzzleHTTP 在现有页面上返回 404
【发布时间】:2019-09-10 08:40:11
【问题描述】:

我对@9​​87654321@ 的 Guzzle POST 请求返回 404,而该页面通过 Postman、浏览器或 javascript 存在。它应该返回 200 和 401 消息,但 Guzzle 会返回 404。在 POST 和 GET 模式下都是这样。

我尝试了多种客户端设置,包括不同的标头和禁用 SSL 验证,但没有任何成功。现在我复制了完全相同的标题,使其在邮递员中工作,但仍然没有成功。

我一直在通过 google 和 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:客户端 错误:POST https://api.scarif.dev/auth 导致404 Not Found 响应: 404 未找到

未找到 (截断...)在 /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}(对象(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 in /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'])
        ]);
    }
}

【问题讨论】:

    标签: php http-status-code-404 guzzle


    【解决方案1】:

    问题似乎来自您正在使用的 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 在任何情况下都不会返回 404,这意味着您的请求甚至可能不会发送到控制器。您是否尝试过返回一个简单的响应以查看是否调用了控制器操作?
    • 好吧这很奇怪,我认为这是我的服务器设置。如果我指向api.scarif.dev,它应该返回一个字符串“欢迎使用 Scarif API”,但它返回“Apache 运行正常”。
    • 一切似乎都很好。 Guzzle 的行为与我使用的任何其他客户端有何不同?有没有办法检查 guzzle 的实际网址是什么?看看是否有任何重定向活动或有什么活动?我的代码中没有。
    • 考虑记录 Guzzle 究竟做了什么。像this 这样的东西应该有助于解决这个问题。
    • 嗯,看来我的 SSL 通配符无法正常工作。它是通过 DirectAdmin 在 Scarif.dev 上设置的,但我已将 api.scarif.dev 和 login.scarif.dev 添加为单独的域,在它们上安装了相同的证书,但它们以自签名证书的形式返回,而我的浏览器说不同。有趣:/
    【解决方案2】:

    我遇到了同样的问题,一直在寻找解决方案,直到我来到这里。虽然没有在线获得任何帮助,其他人的解决方案对我不起作用,但后来我通过大量调试解决了自己,我正在分享解决方案,希望它可以在未来对其他人有所帮助。

    场景:在我的例子中,我有一个 API 网关和客户端(在我的例子中是邮递员)正在向 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>"]
    

    然后它运行良好,经过几天的连续谷歌搜索,我松了一口气。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-28
      • 2020-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-09
      • 2011-11-22
      相关资源
      最近更新 更多