Aws4 sign S3 PUT requests - javascript

Writing specialized S3 file upload request signing function that will run on Cloudflare workers (I guess should be the same as in browsers):
let s3PutSign = function(region, keyId, keySecret, contentType, date, bucket, fileName) {
return crypto.subtle.importKey('raw', new TextEncoder().encode(keySecret), { name: 'HMAC', hash: 'SHA-256' }, true, ['sign'])
.then(key => {
let path = `/${bucket}/${fileName}`
let strToSign = `PUT\n\n${contentType}\n${date}\n${path}`
return crypto.subtle.sign('HMAC', key, new TextEncoder().encode(strToSign))
.then(sig => {
return {
url: `https://s3.${region}.amazonaws.com${path}`,
headers: {
'content-type': contentType,
'Authorization': `AWS ${keyId}:${btoa(sig)}`,
'x-amz-date': new Date(new Date().getTime() + 10000).toISOString().replace(/[:\-]|\.\d{3}/g, '').substr(0, 17)
}
}
})
})
}
Wrote function using PUT example: https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
Variable strToSign:
PUT
application/pdf
Wed, 27 May 2020 12:26:33 GMT
/mybucket/file.pdf
function result:
{
url: "https://s3.eu-central-1.amazonaws.com/mybucket/file.pdf",
headers: {
content-type: "application/pdf",
Authorization: "AWS AKXAJE7XIIVXQZ4X7FXQ:W29iamVXZCBBcnJheUJ1ZmZlcl0=",
x-amz-date: "20200527T122643Z"
}
}
Requests always result this response:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InvalidRequest</Code>
<Message>The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.</Message>
<RequestId>7CECC87D5E855C48</RequestId>
<HostId>rtGLR0u9Qc29bllgKnJf7xD00iQ0+/BZog5G/wYWjsN8tkXio9Baq7GZvbQTD40EVCQ9FzuCo9c=</HostId>
</Error>
Please advise how to debug or give a hint what could be wrong with this function.

Researching this a bit, it seems that AWS4-HMAC-SHA256 may define a specific hashing algorithm. Looking at this (awesome) gist, the author calls out the full algo name.
You might try replacing your call ({ name: 'HMAC', hash: 'SHA-256' }) with { name: 'HMAC', hash: 'AWS4-HMAC-SHA256' }
Another thought is to remove the dash (-) from your algorithm name. Go from SHA-256 to SHA256 and see if that makes a diff.

I know the post is not new, but maybe it will help someone else. :)
Here is a working code example, that I gathered from AWS documentation and some other sources.
// make the call
let signer = new S3Signer(body,'ACCESKEYS','SECRETACCESSKEY','us-east-1','my-test-bucket23.s3.us-east-1.amazonaws.com','/something/SOME/2023/02/some6.pdf','multipart/form-data');
let signerRes = await signer.makeTheCall();
// implementation
const axios = require('axios');
const crypto = require('crypto');
class S3Signer {
constructor(body, accessKey, secretKey, region, host, path, contentType) {
this.region = region; //'us-east-1';
this.host = host; // `my-test-bucket23.s3.us-east-1.amazonaws.com`
this.method = 'PUT';
this.service = 's3';
this.path = path; // `/something/SOME/2023/02/some6.pdf`
this.url = `https://${this.host}${this.path}`;
this.contentType = contentType; //'multipart/form-data';
this.amzDate = null;
this.body = body;
//this.bodyUTF8 = body.toString('utf8');
this.algorithm = 'AWS4-HMAC-SHA256';
this.credentialScope = '';
this.signedHeaders = 'content-type;host;x-amz-content-sha256;x-amz-date';
this.accessKey = accessKey;
this.secretKey = secretKey;
}
getSignatureKey = (key, dateStamp, regionName, serviceName) => {
let kDate = this.hmac(('AWS4' + key), dateStamp);
let kRegion = this.hmac(kDate, regionName);
let kService = this.hmac(kRegion, serviceName);
let kSigning = this.hmac(kService, 'aws4_request');
return kSigning;
}
makeTheCall = async () => {
let canonicalRequest = this.createCanonicalReq();
let signature = this.calculateSignature(canonicalRequest);
// ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************
// Put the signature information in a header named Authorization.
let authorizationHeader = this.algorithm + ' ' + 'Credential=' + this.accessKey + '/' + this.credentialScope + ', ' + 'SignedHeaders=' + this.signedHeaders + ', ' + 'Signature=' + signature;
// For DynamoDB, the request can include any headers, but MUST include "host", "x-amz-date",
// "x-amz-target", "content-type", and "Authorization". Except for the authorization
// header, the headers must be included in the canonical_headers and signed_headers values, as
// noted earlier. Order here is not significant.
//// Python note: The 'host' header is added automatically by the Python 'requests' library.
let headers = {
'Authorization': authorizationHeader,
'Content-Type': this.contentType,
'X-Amz-Content-Sha256' : this.hash(this.body, 'hex'),
'X-Amz-Date': this.amzDate
}
let request = {
host: this.host,
method: this.method,
url: this.url,
data: this.body,
body: this.body,
path: this.path,
headers: headers
}
// send the file to s3
let res = await axios(request);
console.log(res);
return res;
}
calculateSignature = (canonicalReq) => {
// SHA-256 (recommended)
let dateStamp = this.amzDate.substring(0, 8);
this.credentialScope = dateStamp + '/' + this.region + '/' + this.service + '/' + 'aws4_request'
let stringSign = this.algorithm + '\n' + this.amzDate + '\n' + this.credentialScope + '\n' + this.hash(canonicalReq, 'hex')
// ************* TASK 3: CALCULATE THE SIGNATURE *************
// Create the signing key using the function defined above.
let signingKey = this.getSignatureKey(this.secretKey, dateStamp, this.region, this.service);
// Sign the string_to_sign using the signing_key
let signature = this.hmac(signingKey, stringSign, 'hex');
return signature;
}
createCanonicalReq = () => {
// ************* TASK 1: CREATE A CANONICAL REQUEST *************
// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
// Step 1 is to define the verb (GET, POST, etc.)--already done.
// Step 2: Create canonical URI--the part of the URI from domain to query
// string (use '/' if no path)
let canonical_uri = this.path;
//// Step 3: Create the canonical query string. In this example, request
// parameters are passed in the body of the request and the query string
// is blank.
let canonical_querystring = '';
///// set the date
let date = new Date();
this.amzDate = date.toISOString().replace(/[:\-]|\.\d{3}/g, '')
// Step 4: Create the canonical headers. Header names must be trimmed
// and lowercase, and sorted in code point order from low to high.
// Note that there is a trailing \n.
let canonical_headers = 'content-type:' + this.contentType + '\n' + 'host:' + this.host + '\n'
+ 'x-amz-content-sha256:' + this.hash(this.body, 'hex') + '\n'
+ 'x-amz-date:' + this.amzDate + '\n'
// Step 5: Create the list of signed headers. This lists the headers
// in the canonical_headers list, delimited with ";" and in alpha order.
// Note: The request can include any headers; canonical_headers and
// signed_headers include those that you want to be included in the
// hash of the request. "Host" and "x-amz-date" are always required.
// For DynamoDB, content-type and x-amz-target are also required.
//this.signedHeaders = 'content-type;host;x-amz-date'
// Step 6: Create payload hash. In this example, the payload (body of
// the request) contains the request parameters.
let payload_hash = this.hash(this.body, 'hex');
// Step 7: Combine elements to create canonical request
let canonicalRequest = this.method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + this.signedHeaders + '\n' + payload_hash
return canonicalRequest;
}
hmac = (key, string, encoding) => {
return crypto.createHmac('sha256', key).update(string, 'utf8').digest(encoding)
}
hash = (string, encoding) => {
return crypto.createHash('sha256').update(string, 'utf8').digest(encoding)
}
// This function assumes the string has already been percent encoded
// only if you have reuquest query
encodeRfc3986 = (urlEncodedString) => {
return urlEncodedString.replace(/[!'()*]/g, (c) => {
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
})
}
}

Related

Calling NetSuite RESTlet from Javascript: "Invalid Login Attempt"

I'm trying to test my javascript code online via Programiz
but I'm having trouble figuring out where I'm going wrong. Please send help.
Here's the response that I'm getting when I send the request: {"error" : {"code" : "INVALID_LOGIN_ATTEMPT", "message" : "Invalid login attempt."}}
And when I check via Login Audit Trail in NetSuite, the Role is not showing compared to when I tried using POSTMAN.
var crypto = require("crypto");
var fetch = require('node-fetch');
var url = "https://{accountID}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=729&deploy=1";
var realm = "{accountId}";
var signatureMethod = "HMAC-SHA256";
var oauthVersion = "1.0";
var consumerKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var consumerSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var tokenId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var tokenSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var nonce = randomString(10);
var timeStamp = Math.round((new Date()).getTime() / 1000);
var baseString = realm + "&" + consumerKey + "&" + tokenId + "&" + nonce + "&" + timeStamp;
var signingKey = consumerSecret + "&" + tokenSecret;
var hmac = crypto.createHmac("sha256", signingKey);
hmac.update(baseString);
var signature = encodeURIComponent(hmac.digest("base64"));
var authorizationStr = "OAuth realm=\""+ realm + "\"" +
",oauth_consumer_key=\"" + consumerKey + "\"" +
",oauth_token=\"" + tokenId + "\"" +
",oauth_signature_method=\"" + signatureMethod + "\"" +
",oauth_timestamp=\"" + timeStamp + "\"" +
",oauth_nonce=\"" + nonce + "\"" +
",oauth_version=\"" + oauthVersion + "\"" +
",oauth_signature=\"" + signature + "\"";
console.log("timeStamp: " + timeStamp);
console.log("nonce: " + nonce);
console.log("signature: " + signature);
var raw = JSON.stringify({
"searchId": "customsearch_pendingso"
});
var requestOptions = {
method: 'POST',
headers: {
"Authorization": authorizationStr,
"Content-Type": "application/json",
"Cookie": "NS_ROUTING_VERSION=LAGGING",
"Cache-Control": "no-cache",
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br"
},
body: raw,
redirect: 'follow'
};
fetch(url, requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
function randomString(length) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
Here's the solution to my problem.
So instead of trying to do it on an online compiler, I installed NodeJS and used oauth-1.0a.
var request = require('request');
var OAuth = require('oauth-1.0a');
var realm = "{ACCOUNTID}";
var token = {
public: "{TOKEN_ID}",
secret: "{TOKEN_SECRET}"
};
var oauth = OAuth({
consumer: {
public: "{CONSUMER_KEY}",
secret: "{CONSUMER_SECRET}"
},
signature_method: "HMAC-SHA256"
});
var request_data = {
url: "{RESTLET_EXTERNAL_URL}",
method: 'POST'
};
var request_headers = oauth.toHeader(oauth.authorize(request_data, token));
request_headers.Authorization += ', realm="' + realm + '"';
request_headers['content-type'] = 'application/json';
var request_payload = {
"searchId": "customsearch_pendingso"
}
request({
url: request_data.url,
method: request_data.method,
headers: request_headers,
json: request_payload
}, function(error, response, body) {
if (error) console.log(error);
console.log(body);
});

Check if UUID is included in pastebin

I would like for to check if my UUID is includedin my pastebin.
Any idea how I can check that in JavaScript?
The code to actually get the UUID is this:
// GET UUID
const execSync = require("child_process").execSync;
const { type } = require("os");
const { SSL_OP_EPHEMERAL_RSA } = require("constants");
let response = execSync("wmic csproduct get uuid");
let serial = String(response).split("\n")[1];
console.log(serial);
async function fetchText() {
let response = await fetch("https://pastebin.com/raw/4hxgLxyd");
let data = await response.text();
console.log(data.indexOf(serial));
if (data.indexOf(serial) !== -1) {
console.log("included");
} else {
console.log("not included");
}
}
fetchText();
I am new to JS - in Python I know how to check it with a request command.
Anyone knows how to handle this in JS maybe?
As requested my Python code:
def init(): # check HWID
try:
HWID = subprocess.check_output('wmic csproduct get uuid').decode().split('\n')[1].strip()
except:
cmd = "system_profiler SPHardwareDataType | grep 'Serial Number' | awk '{print $4}'"
result = subprocess.run(cmd, stdout=subprocess.PIPE, shell=True, check=True)
HWID = result.stdout.decode().strip()
print('Checking license...')
# -------------------------------------------
# Below this - I need the code for JavaScript
# -------------------------------------------
r = requests.get('https://pastebin.com/xxx')
try:
if HWID in r.text:
pass
else:
print('[ERROR] HWID not registered!')
print(f'HWID: {HWID}')
time.sleep(5)
sys.exit(0)
except:
print('[ERROR] Failed to initiate')
time.sleep(5)
sys.exit(0)
print(f'HWID: {HWID}')
print('--- License is valid ---')
In javascript, you can use indexOf to search for the occurrence of a string. The function will return -1 if it does not exist, otherwise the index the first occurrence.
Additionally, make sure you account for things like case sensitivity and placement of dashes and whitespace.
var str = "Hello world, welcome to the universe.";
var n = str.indexOf("welcome");
See the Node.Js documentation for performing the http request.
// GET UUID
const execSync = require("child_process").execSync;
const response = execSync("wmic csproduct get uuid");
const serial = String(response).split("\n")[1].replace("-", "").trim().toLowerCase();
const https = require('https')
const options = {
hostname: 'pastebin.com',
port: 443,
path: '/xxx',
method: 'GET'
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
var dnorm= d.replace("-", "").trim().toLowerCase();
process.stdout.write(dnorm.indexOf(serial))
})
})
req.on('error', error => {
console.error(error)
})
req.end()
Since it appears you are having a whitespace or encoding issue, please manually compare the contents of the string:
function debugComp(a, b)
{
a= a.toString().trim();
b= a.toString().trim();
console.log("a: '" + a + "' - Length: " + a.length);
console.log("b: '" + b + "' - Length: " + b.length);
if(a.indexOf(b)>-1)
{
console.log("Found at index " + a.indexOf(b));
}
else if(a.length==b.length)
{
for(var i=0; i< a.length; i++)
{
console.log("a[" + i + "]= '" + a[i] + "' - b[" + i + "] = '" + b[i]);
console.log("a[" + i + "] == b[" + i+ "] = " + (a[i]==b[i]));
}
}
else {
console.log("Strings have different lengths");
}
}
debugComp("D340D9AE-A43F-DF47-AFED-A93222AB3646", "D340D9AE-A43F-DF47-AFED-A93222AB3646");

Incomplete JSON data when saving to database in google cloud functions

I am now trying out how to use the Google cloud functions as part of my IOT application.
But I am having issues when I send a JSON POST to the trigger endpoint. There are times that it works perfectly and sometimes the payload hex is cut in the middle.
For example the original payloadhex would be "0011029e02ffb1ffd6ffd8ffdaffe0fff500000008" and sometimes get suddenly cut to "0011029e02ffb1" when it is being saved to the database.
How I test the endpoint would be that I would send an HTTP POST using Postman with data below.
{
"DevEUI_uplink": {
"DevEUI": "BC9740FFFE10549E",
"payload_hex": "0011029e02ffb1ffd6ffd8ffdaffe0fff500000008",
}}
And inside the cloud function would be the nodejs12 code:
/**
* Responds to any HTTP request.
*
* #param {!express:Request} req HTTP request context.
* #param {!express:Response} res HTTP response context.
*/
const moment = require("moment");
const mysql = require("mysql");
require("dotenv").config();
exports.saveFunction = (req, res) => {
let now = moment().format('YYYY-MM-DD HH:mm:ss');
let deveui = req.body.DevEUI_uplink.DevEUI;
let payload = req.body.DevEUI_uplink.payload_hex;
function convertTempData(data) {
data = parseInt(data, 16);
if ((data & 0x8000) > 0) {
data = data - 0x10000;
}
return data;
}
// Slice the Request Data
let raw_payload = payload;
let version = parseInt(payload.slice(0, 2), 16);
let gem1 = parseInt(payload.slice(2, 4), 16);
let gem2 = parseInt(payload.slice(4, 6), 16);
let battery = parseInt(payload.slice(6, 8), 16) / 2;
let payload_id = parseInt(payload.slice(8, 10), 16);
let tempNow = convertTempData(payload.slice(10, 14));
let tempVar1 = convertTempData(payload.slice(14, 18));
let tempVar2 = convertTempData(payload.slice(18, 22));
let tempVar3 = convertTempData(payload.slice(22, 26));
let tempVar4 = convertTempData(payload.slice(26, 30));
let tempVar5 = convertTempData(payload.slice(30, 34));
let tempVar6 = convertTempData(payload.slice(34, 38));
let tempVar7 = convertTempData(payload.slice(38, 42));
// Connection String
const conn = mysql.createConnection({
host: process.env.SERVER_HOST,
user: process.env.SERVER_USER,
password: process.env.SERVER_PASS,
database: process.env.SERVER_DB,
port: process.env.SERVER_PORT,
});
conn.connect(function (err) {
if (err) {
return res
.status(404)
.json({ message: "Invalid Request", error: err.message });
}
var sqlcoms =
"UPDATE sd_payload SET payload = '" +
raw_payload +
"' , version='" +
version +
"', gem1='" +
gem1 +
"' , gem2='" +
gem2 +
"' , battery='" +
battery +
"',payload_id='" +
payload_id +
"',tempNow='" +
tempNow +
"',tempVar1='" +
tempVar1 +
"',tempVar2='" +
tempVar2 +
"',tempVar3='" +
tempVar3 +
"',tempVar4='" +
tempVar4 +
"',tempVar5='" +
tempVar5 +
"',tempVar6='" +
tempVar6 +
"',tempVar7='" +
tempVar7 +
"',updated_at='" +
now +
"' WHERE DevEUI = '" +
deveui +
"'";
conn.query(sqlcoms, function (err, result) {
if (err) {
return res
.status(404)
.json({ message: "Invalid Request", error: err.message });
}
return res.status(201).json(result);
});
});
};
I wanted to save the entire payload to the database for checking purposes. Would you be able to advise why the post json body is being cut midway in some inserts and some inserts would be complete?
I would suggest to first console.log(payload) so to verify if it's received in full by the function, or it gets chopped somewhere on the way.

Cryptopia API in Google Sheet - Signature does not match request parameters

I am trying to connect to Cryptopia API to get my balance in Google Sheet and I can't make it work. The error I am currently getting is:
Signature does not match request parameters
API Private Documentation
My code:
var key1 = "API_KEY";
var secret1 = "API_SECRET";
var nonce = Math.floor(new Date().getTime()/1000);
var params = {"Currency" : "BTC"};
var url = 'https://www.cryptopia.co.nz/api/GetBalance';
var requestContentBase64String = Utilities.base64Encode(Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, JSON.stringify(params), Utilities.Charset.UTF_8)); // Added
var signature = key1 + "POST" + encodeURIComponent(url).toLowerCase() + nonce + requestContentBase64String; // Modified
var hmacsignature = Utilities.base64Encode(Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, signature, Utilities.base64Decode(secret1), Utilities.Charset.UTF_8)); // Modified
var header_value = "amx " + key1 + ":" + hmacsignature + ":" + nonce;
var headers = {
"Authorization": header_value,
"Content-Type": 'application/json; charset=utf-8'
//"Content-Length" : Utilities.newBlob(JSON.stringify(params)).getBytes().length // Added
};
var options = {
"method": 'POST',
"headers": headers,
"payload": JSON.stringify(params),
"contentLength": JSON.stringify(params).length
};
var response = UrlFetchApp.fetch(url, options);
Logger.log(response)
return JSON.parse(response.getContentText());
There is one more thread regarding the same issue on stackoverflow but without correct answer.
Thank you

Azure Log Analytics POST / Search Query in Plain HTML using javascript

I want to Upload an event to Azure LOG Analytics and Retrieve an event using plain JavaScript with XMLHTTPRequest or JQuery rest .
1.Using powershell invoke-webrequest, i am able to Upload the event but not through the below request from html
2. Need help in retrieving an event from Azure Log Analytics RestApi
for the first one Here is the sample code HTTP405: BAD METHOD - The HTTP verb used is not supported.
var strBody = {
"Hostname": "sdfsfsdf",
"Customer": "sdfsfdsfdsf",
"RoundTripLatencyInMs": 67,
};
debugger;
customerId = "xxxxxxxxxxxxxxx";
sharedkey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
logType = "xxxxxxxxx";
TimeStampField = "YYYY-MM-DDThh:mm:ssZ";
// encodebody = stringToUtf16ByteArray(JSON.stringify(strBody).toString('utf8'));//encode_utf8(JSON.stringify(strBody));
str = strBody;
var byteArray = [];
for (var i = 0; i < str.length; i++)
if (str.charCodeAt(i) <= 0x7F)
byteArray.push(str.charCodeAt(i));
else {
var h = encodeURIComponent(str.charAt(i)).substr(1).split('%');
for (var j = 0; j < h.length; j++)
byteArray.push(parseInt(h[j], 16));
}
// return byteArray;
encodebody = byteArray;
method = 'POST';
resource = '/api/logs';
//contentType = 'application/json; charset=utf-8';
var d =new Date();
msdate = d.toUTCString(); //'Thu, 14 Jul 2017 06:35:52 GMT';
contentLength = encodebody.length;
//Signature
xHeaders = "x-ms-date:" + msdate;
stringToHash = method + "\n" + contentLength + "\n" + xHeaders + "\n" + resource;
//message=stringToHash;
var hash = CryptoJS.HmacSHA256(stringToHash, sharedkey);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
// document.write(hashInBase64);
//authorization = 'SharedKey ' + customerId +':'+ hashInBase64 ;
signature = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(CryptoJS.enc.Utf8.parse(stringToHash), CryptoJS.enc.Base64.parse(sharedkey)));
authorization = 'SharedKey ' + customerId + ':' + signature;
uri = "https://" + customerId + ".ods.opinsights.azure.com" + resource + "?api-version=2016-04-01";
var myHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
debugger;
$.ajax({
url: uri,
type: 'POST',
success: function (data) {
//do something to data
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', "SharedKey " + customerId + ":" + signature);
xhr.setRequestHeader('x-ms-date', msdate);
xhr.setRequestHeader('x-ms-version', '2014-02-14');
xhr.setRequestHeader('Accept-Charset', 'UTF-8');
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
//xhr.setRequestHeader('Accept', 'application/json;odata=nometadata');
xhr.setRequestHeader("Log-Type", logType);
xhr.setRequestHeader("time-generated-field", TimeStampField);
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
//xhr.setRequestHeader('DataServiceVersion', '3.0;NetFx');
//xhr.setRequestHeader('MaxDataServiceVersion', '3.0;NetFx');
},
datatype:'json',
//contentType: 'application/json',
data:encodebody,
error: function (rcvData) {
console.log("ERRor");
console.log(rcvData);
}
});
Any pointers will be helpfull
As you made a REST call from browser side using javascript, the browser would first send an HTTP request by the OPTIONS method to the resource to look for CORS headers. See Preflighted requests. And Log Analytics REST API doesn't allow the OPTIONS HTTP verb. It means that the API doesn't support CORS. So, it raises your issue.
So, you should call the REST API by using server side language like PHP, Python, Node.js, etc.

Categories