Reputation: 3
I try to connect an API RestLet with my proyect from Laravel. I used Http class from Facade and I get the message "Invalid loging attempt".
array:1 [▼
"error" => array:2 [▼
"code" => "INVALID_LOGIN_ATTEMPT"
"message" => "Invalid login attempt."
]
]
This is my block-code:
use Illuminate\Support\Facades\Http;
public function test() {
$realm = "*****";
$consumerKey = "*********";
$consumerSecret = "********";
$token = "********";
$tokenSecret = "********";
$oauthTimestamp = time();
$oauthNonce = bin2hex(random_bytes(6));
$baseUrl = 'http**********';
$params = [
'script' => '****',
'deploy' => '*'
];
$body = json_encode(["mensaje" => "test message"], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$oauthBodyHash = base64_encode(hash('sha256', $body, true));
$oauthBodyHash = rawurlencode($oauthBodyHash);
$oauthParams = [
'realm' => $realm,
'oauth_consumer_key' => $consumerKey,
'oauth_token' => $token,
'oauth_signature_method' => 'HMAC-SHA256',
'oauth_timestamp' => $oauthTimestamp,
'oauth_nonce' => $oauthNonce,
'oauth_version' => '1.0',
'oauth_body_hash' => $oauthBodyHash
];
$oauthSignature = generateOauthSignature('GET', $baseUrl, array_merge($oauthParams, $params), $consumerSecret, $tokenSecret);
$oauthParams['oauth_signature'] = rawurlencode($oauthSignature);
$params = Arr::map($oauthParams, function ( $value, $key) {
return '"' . $value . '"';
});
$authorizationHeader = "OAuth " . urldecode(http_build_query($params, '', ','));
$fullUrl = $baseUrl . '?' . http_build_query($params);
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization' => $authorizationHeader
])->timeout(0)
->get($fullUrl);
$data = $response->json();
dd($data); //
}
function generateOauthSignature($method, $baseUrl, $params, $consumerSecret, $tokenSecret) {
unset($params['realm']);
ksort($params);
$encodedParams = [];
foreach ($params as $key => $value) {
$encodedParams[] = rawurlencode($key) . "=" . rawurlencode($value);
}
$paramString = implode("&", $encodedParams);
$baseString = strtoupper($method) . "&" . rawurlencode($baseUrl) . "&" . rawurlencode($paramString);
$signingKey = rawurlencode($consumerSecret) . "&" . rawurlencode($tokenSecret);
$signature = base64_encode(hash_hmac('sha256', $baseString, $signingKey, true));
return $signature;
}
Before the coding my petition, I proved in POSTMAN and get a good responce, but don't in my proyect Laravel despite I used the same credentials.
If someone have connected an API RestLet in Laravel, please tellme how. I'll gratefully
I try to resolve my problem and connect ma proyect Laravel with my API RestLet from NetSuite
Upvotes: 0
Views: 32
Reputation: 446
I've done this before and haven't had this problem. ensure that your OAuth signature and header are built exactly the way NetSuite expects, and that your request method and parameters match what worked in Postman. For a NetSuite RESTlet, the typical approach is to send the OAuth parameters in the "Authorization" header and include "script" and "deploy" as query parameters. Also, if you're sending JSON data in a request body, you usually want a POST call and an "oauth_body_hash" in the signature. Here's an example that might help:
use Illuminate\Support\Facades\Http;
public function callRestlet()
{
$realm = 'YOUR_REALM';
$consumerKey = 'YOUR_CONSUMER_KEY';
$consumerSecret = 'YOUR_CONSUMER_SECRET';
$token = 'YOUR_TOKEN';
$tokenSecret = 'YOUR_TOKEN_SECRET';
$baseUrl = 'https://rest.netsuite.com/app/site/hosting/restlet.nl';
$scriptId = 'YOUR_SCRIPT_ID';
$deployId = 'YOUR_DEPLOY_ID';
// Build the JSON body
$bodyArray = ['mensaje' => 'Hello from Laravel'];
$jsonBody = json_encode($bodyArray);
// Build OAuth params
$oauthNonce = bin2hex(random_bytes(16));
$oauthTimestamp = time();
$oauthBodyHash = base64_encode(hash('sha256', $jsonBody, true));
$oauthParams = [
'oauth_consumer_key' => $consumerKey,
'oauth_nonce' => $oauthNonce,
'oauth_signature_method' => 'HMAC-SHA256',
'oauth_timestamp' => $oauthTimestamp,
'oauth_token' => $token,
'oauth_version' => '1.0',
'oauth_body_hash' => $oauthBodyHash
];
// Signature base string
$allParams = array_merge($oauthParams, [
'script' => $scriptId,
'deploy' => $deployId
]);
ksort($allParams);
$encodedParams = [];
foreach ($allParams as $key => $value) {
$encodedParams[] = rawurlencode($key) . '=' . rawurlencode($value);
}
$baseString = 'POST&' . rawurlencode($baseUrl) . '&' . rawurlencode(implode('&', $encodedParams));
$signingKey = rawurlencode($consumerSecret) . '&' . rawurlencode($tokenSecret);
$oauthSignature = base64_encode(hash_hmac('sha256', $baseString, $signingKey, true));
$oauthParams['oauth_signature'] = $oauthSignature;
// Build Authorization header
$headerArray = [];
foreach ($oauthParams as $k => $v) {
$headerArray[] = $k . '="' . rawurlencode($v) . '"';
}
$headerArray[] = 'realm="' . rawurlencode($realm) . '"';
$authorizationHeader = 'OAuth ' . implode(', ', $headerArray);
// Make the request
$query = "?script={$scriptId}&deploy={$deployId}";
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization' => $authorizationHeader
])->post($baseUrl . $query, $bodyArray);
return $response->body();
}
this is just a sample code. Make sure you use the same HTTP method in Laravel that worked in Postman, keep your "script" and "deploy" values in the query string, and include the correct "oauth_body_hash" if you're sending JSON content. i think the most common issue is a mismatch in how the signature is generated or how the OAuth header is formatted compared to the requirements
Upvotes: 0