netsuite oauth 1.0 php对接踩坑记录

23-08-28 15:35 字数 3196 阅读 832 已编辑

业务需要对接netsuite的接口,对方接口验权是oauth1.0,根据提供的consumerKey等参数,使用postman测试了一下,可以调通。

postman

然后写代码实现如下:

// 请求URL
$baseUrl = "https://xxxx.restlets.api.netsuite.com/app/site/hosting/restlet.nl";
$deploy = 1;
$script = 226;

// 请求参数
$postData = ['aaa' => 'bbb'];
$postData = json_encode($postData);

// OAuth1.0认证参数
$consumerKey = "xxxxx";
$consumerSecret = "xxxxx";
$accessToken = "xxxxx";
$tokenSecret = "xxxxx";

// 生成OAuth1.0头部
$timestamp = time();
$signatureMethod = "HMAC-SHA256";
$nonce = md5(mt_rand());
$version = "1.0";
$realm = "7023245_SB1";

$baseString =
    "POST&" . urlencode($baseUrl) . "&" .
    urlencode(
        "deploy=" . $deploy
        . "&oauth_consumer_key=" . $consumerKey
        . "&oauth_nonce=" . $nonce
        . "&oauth_signature_method=" . $signatureMethod
        . "&oauth_timestamp=" . $timestamp
        . "&oauth_token=" . $accessToken
        . "&oauth_version=" . $version
        . "&realm=" . $realm
        . "&script=" . $script
    );

$signString = urlencode($consumerSecret) . '&' . urlencode($tokenSecret);
$signature = base64_encode(hash_hmac("sha256", $baseString, $signString, true));

// header参数
$header = [
    "Authorization: OAuth "
    . 'oauth_signature="' . rawurlencode($signature) . '", '
    . 'oauth_version="' . rawurlencode($version) . '", '
    . 'oauth_nonce="' . rawurlencode($nonce) . '", '
    . 'oauth_signature_method="' . rawurlencode($signatureMethod) . '", '
    . 'oauth_consumer_key="' . rawurlencode($consumerKey) . '", '
    . 'oauth_token="' . rawurlencode($accessToken) . '", '
    . 'oauth_timestamp="' . rawurlencode($timestamp) . '", '
    . 'realm="' . rawurlencode($realm) . '"',
    "Content-Type: application/json",
    'Content-Length: ' . strlen($postData)
];
$url = "{$baseUrl}?script={$script}&deploy={$deploy}";
$result = callHttpRequest($url, 'POST', $postData, $header);
var_dump($url, $header, $postData, $result);
exit;

function callHttpRequest($url, $method = 'POST', $data = [], $header = [])
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
    curl_setopt($ch, CURLOPT_ENCODING, '');
    curl_setopt($ch, CURLOPT_POST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}

本以为没什么问题,没想到直接报错:

{"error" : {"code" : "INVALID_LOGIN_ATTEMPT", "message" : "Invalid login attempt."}}

奇怪,是哪里出了问题吗?一遍遍的排查,最后直接用postman生成的php代码复制出来跑一下发现还是报同样的错。

这就不合理了啊,为什么和postman一样的参数,加密参数、时间戳、等等都一样,postman能调通,php代码调不通呢。

无奈只能找对方技术询问,显然对方也不是phper,但是给我发了一个帖子 https://stackoverflow.com/questions/32867476/oauth-implementation-in-netsuite-using-php

看了下这篇stackoverflow的帖子,加密方式、拼参数的方法都和我的代码里差不多,正一筹莫展之时,发现帖子里的url里拼了realm参数,难道是因为这个参数导致的,最后把这个参数拼上,再跑一次。

$url = "{$baseUrl}?script={$script}&deploy={$deploy}";

终于看到了久违的200

{"status":"In progress","code":"200 OK","message":"Record sync has been started."}

思考 奇怪的是为什么postman的url里也没加这个参数但是却能调通,代码里不加却不通。

realm解释

1人点赞>
关注 收藏 改进 举报
0 条评论
排序方式 时间 投票
快来抢占一楼吧
请登录后发表评论
站长 @ 十七度
文章
380
粉丝
23
喜欢
191
收藏
31
排名 : 1
访问 : 128.42万
私信