You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP cURL重复请求致MercadoLibre OAuth令牌获取失败

Mercado Libre OAuth Token 获取报错修复方案

问题场景

向https://api.mercadolibre.com/oauth/token发送POST请求,传入新生成的授权code获取access token时,返回错误:

{"cause":[],"error":"invalid_grant","error_description":"Error validating grant. Your authorization code or refresh token may be expired or it was already used","status":400}

问题根源

自定义Request类的httpRequest方法里有两次curl_exec($curl)调用,导致请求被重复发送:第一次请求成功拿到token,但授权code已被消耗;第二次请求因为code已使用,返回上述错误。

修复代码

修改Request类的httpRequest方法,移除重复的curl_exec调用,保留一次执行并正确处理错误:

class Request {

    private function httpRequest(
        string $method,
        string $url,
        array $headers,
        array $data=array()
    ) {
        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => $headers
        ));

        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($curl, CURLOPT_HEADER, 0);

        if ($method != "GET" && $data) {
            curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
        }

        // 仅执行一次curl请求,统一处理错误
        $response = curl_exec($curl);
        if (curl_errno($curl)) {
            $error = curl_errno($curl)." - ".curl_error($curl);
        } elseif ($response === false) {
            trigger_error(curl_error($curl));
        }

        curl_close($curl);
        
        if (isset($error)) {
            return $error;
        }

        return $response;
    }

    // 以下get/post/put方法保持不变
    public function get(
        string $url,
        array $headers,
        array $data=array()
    ) {
        if ($data) {
            $url = Utils::urlParams($url, $data);
        }

        return $this->httpRequest($method = "GET", $url, $headers);
    }

    public function post(
        string $url,
        array $headers,
        array $data=array()
    ) {
        return $this->httpRequest($method = "POST", $url, $headers, $data);
    }

    public function put(
        string $url,
        array $headers,
        array $data
    ) {
        return $this->httpRequest($method = "PUT", $url, $headers, $data);
    }
}

修复说明

  • 删除原代码中第二次$response = curl_exec($curl);调用,避免重复发送请求
  • 调整错误处理逻辑:先执行请求,再判断curl错误,同时保留原有的trigger_error处理请求失败场景
  • 保持CURLOPT_RETURNTRANSFER => true,确保响应内容存入$response变量而非直接输出

验证结果

修复后,调用accessToken方法仅发送一次请求,成功返回有效access token:

{"access_token":"APP_USR-731450979634979-062614-76a6db201965f6c18c1108cebc48fb1d-1405568857","token_type":"Bearer","expires_in":21600,"scope":"offline_access read write","user_id":1405568857,"refresh_token":"TG-6499d6c7eea12900019aba4d-1405568857"}

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 20:52:54