php 缺少必需的参数OAuth API(netsuite)

m3eecexj  于 2022-10-30  发布在  PHP
关注(0)|答案(1)|浏览(235)

在此输入代码我刚开始使用GuzzleHttp\Clientphp调用OAuth1 API。在postman中,它运行正常。在netsuite日志文件中,我可以看到只缺少必需的参数。我不明白我哪里出错了。每当我调用API时,我得到的响应为


# message: """

    Client error: `GET https://7085372.suitetalk.api.netsuite.com/services/rest/record/v1/customer/` resulted in a `400 Bad Request` response:
    {"type":"https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1","title":"Bad Request","status":400,"o:errorD (truncated...)
    """
  #code: 400

php代码

$realm = 'xxxxxxx';
$consumer_key = 'xxxxxxxxx';
$oauth_token = 'xxxxxxxxxxxxx';
$oauth_signature_method = 'HMAC-SHA256';
$oauth_version = '1.0';
$consumer_secret = 'xxxxxxxxxxxxx';
$token_secrect = 'xxxxxxxxxxxxx';
$timeStamp = Carbon::now()->timestamp;
$oauth_none = Str::random(11);

$base = 'GET' . "&" . urlencode('https://7085372.suitetalk.api.netsuite.com/services/rest/record/v1/customer/') . "&" . urlencode("oauth_consumer_key=" . urlencode($consumer_key) . "&oauth_nonce=" . urlencode($oauth_none) . "&oauth_signature_method=" . urlencode($oauth_signature_method) . "&oauth_timestamp=" . urlencode($timeStamp) . "&oauth_token=" . urlencode($oauth_token) . "&oauth_version=" . urlencode($oauth_version) . "&realm=" . urlencode($realm));

$key = urlencode($consumer_secret) . "&" . urlencode($token_secrect);
$oauth_signature = base64_encode(hash_hmac('sha256', $base, $key, true));

$authorization = 'OAuth oauth_consumer_key=' . $consumer_key . ',oauth_nonce=' . $oauth_none . ',oauth_signature_method=' . $oauth_signature_method . ',oauth_timestamp=' . $timeStamp . ',oauth_token=' . $oauth_token . ',oauth_version=' . $oauth_version . ',realm=' . $realm . ',oauth_signature=' . $oauth_signature . '';

        try {
            $client = new Client();
            $headers = [
                'Authorization' => $authorization,
                'Content-Type' => 'application/json',
                'Cookie' => 'NS_ROUTING_VERSION=LAGGING'
            ];
            $body = '';

            $request = new Request('GET', 'https://7085372.suitetalk.api.netsuite.com/services/rest/record/v1/customer/', $headers, $body);
            $res = $client->sendAsync($request)->wait();
            dd('here', $res, $res->getBody());
        } catch (RequestException $e) {
            dd($e->getResponse(), $e);
        }

Postman Collection

vd8tlhqk

vd8tlhqk1#

在此行中:

$base = 'GET' . "&" . urlencode('https://7085372.suitetalk.api.netsuite.com/services/rest/record/v1/customer/') . "&" . urlencode("oauth_consumer_key=" . urlencode($consumer_key) . "&oauth_nonce=" . urlencode($oauth_none) . "&oauth_signature_method=" . urlencode($oauth_signature_method) . "&oauth_timestamp=" . urlencode($timeStamp) . "&oauth_token=" . urlencode($oauth_token) . "&oauth_version=" . urlencode($oauth_version) . "&realm=" . urlencode($realm));

urlencode("oauth_consumer_key=" ."&realm=" . urlencode($realm));,您使用了两次url_encoding,并且您使用了两次url_encoding =符号。因此,您的$authorization字符串绝对是错误的,并且它会导致参数丢失。
当你写这么长的一行时,很难看清。最好是这样写:

$base = 'GET&' . urlencode('https://7085372.suitetalk.api.netsuite.com/services/rest/record/v1/customer/')
    . '&oauth_consumer_key=' . urlencode($consumer_key)
    . '&oauth_nonce=' . urlencode($oauth_none)
    . '&oauth_signature_method=' . urlencode($oauth_signature_method)
    . '&oauth_timestamp=' . urlencode($timeStamp)
    . '&oauth_token=' . urlencode($oauth_token)
    . '&oauth_version=' . urlencode($oauth_version)
    . '&realm=' . urlencode($realm);

但是,使用数组和http_build_query()函数会更好,方法如下:

$url = 'https://7085372.suitetalk.api.netsuite.com/services/rest/record/v1/customer/';

$data = array(
    'oauth_consumer_key' => $consumer_key,
    'oauth_nonce' => $oauth_none,
    'oauth_signature_method' => $oauth_signature_method,
    'oauth_timestamp' => $timeStamp,
    'oauth_token' => $oauth_token,
    'oauth_version' => $oauth_version,
    'realm' => $realm,
);

$base = 'GET&' . urlencode($url) . '&' . http_build_query($data);

注意.-另外,最好为url使用一个变量,因为您要多次使用它。

但是,也许还有更多的问题。我不知道你是否做得很好的要求。
最好有一个生成OAuth签名的函数。

以下是您的代码的重新制作

$url = 'https://7085372.suitetalk.api.netsuite.com/services/rest/record/v1/customer/';
$consumer_secret = 'xxxxxxxxxx';
$token_secret = 'xxxxxxxxxx';
$data = array(
    'oauth_consumer_key' => 'xxxxxxxxxx',
    'oauth_nonce' => Str::random(11),
    'oauth_signature_method' => 'HMAC-SHA256',
    'oauth_timestamp' => Carbon::now()->timestamp,
    'oauth_token' => 'xxxxxxxxxx',
    'oauth_version' => '1.0',
    'realm' => 'xxxxxxxxxx',
);

$oauth_signature = generateOauthSignature(
    'GET',
    $url,
    $data['oauth_consumer_key'],
    $data['oauth_nonce'],
    $data['oauth_signature_method'],
    $data['oauth_timestamp'],
    $data['outh_version'],
    $consumer_secret,
    $token_secret,
    $data['oauth_token'],
    array('realm' => $data['realm']),
);
$authorization = 'OAuth ';
foreach ($data as $key => $val) {
    $authorization .= ',' . $key . '=' . $val;
}
$authorization .= ',oauth_signature=' . $oauth_signature;

try {
    $client = new Client();
    $headers = [
        'Authorization' => $authorization,
        'Content-Type' => 'application/json',
        'Cookie' => 'NS_ROUTING_VERSION=LAGGING'
    ];
    $body = '';

    $request = new Request('GET', $url, $headers, $body);
    $res = $client->sendAsync($request)->wait();
    dd('here', $res, $res->getBody());
} catch (RequestException $e) {
    dd($e->getResponse(), $e);
}

function generateOauthSignature($method, $url, $consumerKey, $nonce, $signatureMethod, $timestamp, $version, $consumerSecret, $tokenSecret, $tokenValue, $extraParams = array())
{
    $base = strtoupper($method) . "&" . rawurlencode($url) . "&"
        . rawurlencode("oauth_consumer_key=" . $consumerKey
        . "&oauth_nonce=" . $nonce
        . "&oauth_signature_method=" . $signatureMethod
        . "&oauth_timestamp=" . $timestamp
        . "&oauth_token=" . $tokenValue
        . "&oauth_version=" . $version);

        if (!empty($extraParams)) {
            $base .= rawurlencode("&" . http_build_query($extraParams));
        }

    $key = rawurlencode($consumerSecret) . '&' . rawurlencode($tokenSecret);
    $signature = base64_encode(hash_hmac('sha1', $base, $key, true));

    return rawurlencode($signature);
}

相关问题