powershell 意外URL编码URI两次,无效签名响应

beq87vna  于 2023-01-20  发布在  Shell
关注(0)|答案(1)|浏览(130)

我将尽力解释这一点。我将尝试对NetSuite "employees" API执行一个简单的GET(使用PowerShell)。正如您在下面的$查询中所看到的,此变量需要进行URL编码(查询中的空格),这是我在下面代码段的第20行所做的。然后,我将该编码URL与其他一些变量一起构建$base_string。base_string来创建Base64 OAuth签名,并在第36行对签名进行URL编码。我从NetSuite得到的响应始终是无效签名。
当我执行任何类型的"标准"查询(如下面的查询,没有空格...表示编码后URL没有变化)时,我没有得到无效签名响应。这使我相信问题完全与我尝试的更独特的查询有关,可能是因为它被"双重编码"。
我将感谢任何反馈,因为我真的会受益于能够对下面代码片段中的"custentity"变量执行查询。

$query =                  "/services/rest/record/v1/employee/$($netsuite_id)" # This query will find a user via their NetSuite ID.
$url =                    "https://$($realm.ToLower().Replace("_","-")).suitetalk.api.netsuite.com"
$query =                  "/services/rest/record/v1/employee?q=custentity_coupa_emp_id IS $($employee_id)" # This query will find a user via a custom entity --- their Coupa ID.
$oauth_nonce =            [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes([System.DateTime]::Now.Ticks.ToString()))
$oauth_timestamp =        [int64](([datetime]::UtcNow)-(Get-Date "1970-01-01")).TotalSeconds

# BUILD THE BASE STRING VARIABLE
$oAuthParamsForSigning = @{}
$oAuthParamsForSigning.Add("oauth_consumer_key",$oauth_consumer_key)
$oAuthParamsForSigning.Add("oauth_token",$oauth_token)
$oAuthParamsForSigning.Add("oauth_signature_method",$oauth_signature_method)
$oAuthParamsForSigning.Add("oauth_nonce",$oauth_nonce)
$oAuthParamsForSigning.Add("oauth_timestamp",$oauth_timestamp)
$oAuthParamsForSigning.Add("oauth_version",$oauth_version)
$oAuthParamsString = ($oAuthParamsForSigning.Keys | Sort-Object | % {
    "$_=$($oAuthParamsForSigning[$_])"
}) -join "&"
$encodedOAuthParamsString = [uri]::EscapeDataString($oAuthParamsString)

# BUILD THE ENCODED FULL URL VARIABLE
$encodedUrl = [uri]::EscapeDataString($url+$query)

# BUILD THE OAUTH SIGNATURE VARIABLE: KEY (CONSUMER SECRET + TOKEN SECRET) + BASE STRING
$base_string = $HTTP_method + "&" + $encodedUrl + "&" + $encodedOAuthParamsString
$key = $oauth_consumer_secret + "&" + $oauth_token_secret

$hmacsha256 = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha256.Key = [System.Text.Encoding]::ASCII.GetBytes($key)
$oauth_signature = [System.Convert]::ToBase64String($hmacsha256.ComputeHash([System.Text.Encoding]::ASCII.GetBytes($base_string)))

# BUILD THE HEADERS VARIABLE
$authHeaderString = ($oAuthParamsForSigning.Keys | Sort-Object | % {
    "$_=`"$([uri]::EscapeDataString($oAuthParamsForSigning[$_]))`""
}) -join ","
$authHeaderString += ",realm=`"$([uri]::EscapeDataString($realm))`""
$authHeaderString += ",oauth_signature=`"$([uri]::EscapeDataString($oauth_signature))`""
$authHeaders = @{
    "Content-Type"="application/json"
    ;"Prefer"="transient"
    ;"Authorization"="OAuth $authHeaderString"
    ;"Accept"="*/*"
    ;"Cache-Control"="no-cache"
    ;"Host"="3489459-sb1.suitetalk.api.netsuite.com"
    ;"Accept-Encoding"="gzip, deflate, br"
    ;"Cookie"="NS_ROUTING_VERSION=LAGGING"
}
eiee3dmh

eiee3dmh1#

我没有使用PowerShell的背景,但我以前使用Python时遇到过这个问题,不使用库会很棘手。我发现:

  • 基本URL不能包含query params。这意味着基本URL应为:

"https://$($realm.ToLower().Replace("_","-")).suitetalk.api.netsuite.com/services/rest/record/v1/employee"

  • 由于您只执行GET请求,因此只需将查询放入有效负载(JSON格式)。至少在我的SuiteQL中,我是这样做的。将查询移到有效负载对我来说很有效。
  • 对于POST请求,需要将参数包含在基本字符串创建中,如果关键字具有相同名称,则按字母顺序或值排序。

例如,我对SuiteQL的查询是query = json.dumps({ q: SELECT FROM WHERE })

相关问题