Javascript Fetch Authorization Header - javascript

I know, there are a lot of those questions out here but none of them seem to help me with my question so im sorry if im just not able to understand the other questions, so here i come:
I want to use oauth wit discogs.com Prodiver in my react-native app. Since no oauth library fit for Discogs i need to implement this on my own. Discogs documentation tells me which headers i need for my oauth flow (currently at 'request token' step):
Content-Type: application/x-www-form-urlencoded
Authorization:
OAuth oauth_consumer_key="your_consumer_key",
oauth_nonce="random_string_or_timestamp",
oauth_signature="your_consumer_secret&",
oauth_signature_method="PLAINTEXT",
oauth_timestamp="current_timestamp",
oauth_callback="your_callback"
User-Agent: some_user_agent
How can i make a get request with javascript and fetch and include those headers? My code right now seems fine to a beginner like me, but it wont get approved by discogs oauth endpoint:
const header = new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/vnd.discogs.v2.plaintext+json',
Authorization: {
'OAuth oauth_consumer_key': config.consumerKey, //imported from json
'oauth_nonce': nonce, //variable
'oauth_signature': config.consumerSecret, // imported from json
'oauth_signature_method': "PLAINTEXT",
'oauth_timestamp': timestamp, // variable
'oauth_callback': callback // variable
},
'User-Agent': config.appUserAgent
})
console.log(header)
const response = await fetch(https://api.discogs.com/oauth/request_token, {
method: 'GET',
headers: header
});
console.log(response)
The console log of headers and response logs this:
{
"map": {
"content-type": "application/x-www-form-urlencoded",
"accept": "application/vnd.discogs.v2.plaintext+json",
"authorization": "[object Object]",
"user-agent": "Jukebox/1.0"
}
}
{"_bodyBlob": {"_data": {"__collector": [Object], "blobId": "F020B207-2E76-46C8-AD23-783A582B873D", "name": "request_token.json", "offset": 0, "size": 90, "type": "application/json"}}, "_bodyInit": {"_data": {"__collector": [Object], "blobId": "F020B207-2E76-46C8-AD23-783A582B873D", "name": "request_token.json", "offset": 0, "size": 90, "type": "application/json"}}, "bodyUsed": false, "headers": {"map": {"access-control-allow-headers": "Content-Type, authorization, User-Agent, Private-Auth-Secret, Discogs-UID", "access-control-allow-methods": "HEAD,OPTIONS,OPTIONS", "access-control-allow-origin": "*", "access-control-expose-headers": "Location", "alt-svc": "h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", "cf-ray": "79c05b750af01608-DUS", "content-language": "de", "content-length": "90", "content-type": "application/json", "date": "Sun, 19 Feb 2023 16:25:13 GMT", "server": "cloudflare", "strict-transport-security": "max-age=15552000", "x-content-type-options": "nosniff", "x-discogs-media-type": "discogs.v2", "x-discogs-ratelimit": "60", "x-discogs-ratelimit-remaining": "60", "x-discogs-ratelimit-used": "0", "x-frame-options": "SAMEORIGIN", "x-xss-protection": "1; mode=block"}}, "ok": false, "status": 500, "statusText": "", "type": "default", "url": "https://api.discogs.com/oauth/request_token"}

It looks like the Authorization header is not being set correctly in your request. Instead of setting it as an object, you need to set it as a single string that includes all the OAuth parameters.
Here's an example of how you can construct the Authorization header:
const oauthParams = {
oauth_consumer_key: config.consumerKey,
oauth_nonce: nonce,
oauth_signature: `${config.consumerSecret}&`,
oauth_signature_method: 'PLAINTEXT',
oauth_timestamp: timestamp,
oauth_callback: callback,
};
const authHeader = Object.entries(oauthParams)
.map(([key, value]) => `${encodeURIComponent(key)}="${encodeURIComponent(value)}"`)
.join(', ');
const headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/vnd.discogs.v2.plaintext+json',
'Authorization': `OAuth ${authHeader}`,
'User-Agent': config.appUserAgent,
});
const response = await fetch('https://api.discogs.com/oauth/request_token', {
method: 'GET',
headers,
});
const data = await response.json();
console.log(data);
In this example, oauthParams is an object that holds all the OAuth parameters that need to be included in the Authorization header. The authHeader variable is constructed by encoding each key-value pair as a string in the format key="value", and joining them with commas. Finally, the Authorization header is set to "OAuth " + authHeader.
Note that the OAuth parameters must be sorted in alphabetical order by key before being encoded and included in the Authorization header.

Related

Why can access a site through browser, wheares write simple code to fetch, but get 403 error

Endpoint: https://quizlet.com/webapi/3.2/images/search?query=hello&perPage=2
You guys can try to access this page as Incognito, from my side It works. So I think I can fetch data from that site.
I try to copy the request and run in Javascirpt, Python. However, It doesn't work. I got 403 error.
I also try to use Burp Suite. I can't access this site through Burp's browser.
Moreover, As I tried using incognito so I don't think it is relevant to cookies.
Code sample (JS):
import fetch from "node-fetch";
const response = await fetch(
"https://quizlet.com/webapi/3.2/images/search?query=hello&perPage=2",
{
headers: {
accept:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"accept-language": "en",
"cache-control": "no-cache",
pragma: "no-cache",
"sec-ch-ua":
'"Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Linux"',
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "none",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
},
referrerPolicy: "strict-origin-when-cross-origin",
body: null,
method: "GET",
mode: "cors",
credentials: "include",
}
);
const data = await response.status;
console.log(data);
Code Python
import requests
headers = {
'authority': 'quizlet.com',
'pragma': 'no-cache',
'cache-control': 'no-cache',
'sec-ch-ua': '"Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Linux"',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'sec-fetch-site': 'none',
'sec-fetch-mode': 'navigate',
'sec-fetch-user': '?1',
'sec-fetch-dest': 'document',
'accept-language': 'en',
'cookie': 'qi5=i2x3g7y1z9a6%3At3vMoQQig2yLcpN.HKWn; qtkn=7gT4DE7pN9URJ2AFDYeaVe; fs=qzkse0; app_session_id=9781a407-4f37-4c09-8e97-8156f182bb45; search_session=%7B%22search_session_id%22%3A%22-2379864199063990974614477b859794%22%2C%22query%22%3A%22overrated%22%2C%22version%22%3A%221.1.1%22%2C%22platform%22%3A%22WEB%22%2C%22depth%22%3Anull%2C%22target_object_type%22%3A%22QImage%22%7D; __cf_bm=cB7hRf6JbcOFZ2kvQ3W12V4bxXiIgn_kF3n87RcI0h0-1631877048-0-Ac+Hi0pATLgW5N3JjqYa7uc5W4ZfDLOumvmCQixWJIKdcVj7stciFh8cYFVTOpr+q5pM2Q7LrXC/LsffOB6Mh2E=; __cfruid=81f16a673e6117331dd4270b3f4f29111590d7d8-1631877048',
}
params = (
('query', 'hello'),
('perPage', '2'),
)
response = requests.get(
'https://quizlet.com/webapi/3.2/images/search', headers=headers, params=params)
# NB. Original query string below. It seems impossible to parse and
# reproduce query strings 100% accurately so the one below is given
# in case the reproduced version is not "correct".
# response = requests.get('https://quizlet.com/webapi/3.2/images/search?query=hello&perPage=2', headers=headers)
print(response.status_code)
Please help me out. I don't even know how can be that? (browser works, while code doesn't). Thank anyway.
From the python side. I had a look out of interest, as I'm currently developing a REST API and was curious how they where securing it.
Using Wireshark it appears that the "requests" module in python does not handle http requests in the same manor as Chrome/Firefox, which I suspect they are using as a tell to give a captcha.
Anyway switching requests for the httpx module;
pip install httpx
https://www.python-httpx.org/
And changing the headers to replicate Firefox in full;
import httpx
headers = [
('Accept','text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'),
('Accept-Encoding','gzip, deflate, br'),
('Accept-Language','en-GB,en;q=0.5'),
('Cache-Control','max-age=0'),
('Connection','keep-alive'),
('Host','quizlet.com'),
('Sec-Fetch-Dest','document'),
('Sec-Fetch-Mode','navigate'),
('Sec-Fetch-Site','none'),
('Sec-Fetch-User','?1'),
('TE','trailers'),
('Upgrade-Insecure-Requests','1'),
('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0'),
]
params = (
('query', 'hello'),
('perPage', '2'),
)
response = httpx.get('https://quizlet.com/webapi/3.2/images/search', headers=headers, params=params,)
print(response.content)
Gives the following as appose to the captcha page for me;
{
"responses": [{
"models": {
"image": [{
"id": 18957872,
"personId": 16641862,
"timestamp": 1416579222,
"lastModified": 1416579222,
"code": "Gfg5XS88MRmYq8RS",
"license": 1,
"width": 480,
"height": 360,
"flickrId": null,
"flickrOwner": null,
"_legacyUrl": "http://o.quizlet.com/cZDE.6rHW7IrGptXSGm8FA.gif",
"_legacyUrlSquare": "http://o.quizlet.com/cZDE.6rHW7IrGptXSGm8FA_s.gif",
"_legacyUrlSmall": "http://o.quizlet.com/cZDE.6rHW7IrGptXSGm8FA_m.gif",
"_secureLegacyUrl": "https://o.quizlet.com/cZDE.6rHW7IrGptXSGm8FA.gif",
"_secureLegacyUrlLarge": "https://o.quizlet.com/cZDE.6rHW7IrGptXSGm8FA_b.gif",
"_secureLegacyUrlSquare": "https://o.quizlet.com/cZDE.6rHW7IrGptXSGm8FA_s.gif",
"_secureLegacyUrlSmall": "https://o.quizlet.com/cZDE.6rHW7IrGptXSGm8FA_m.gif"
}, {
"id": 9228314,
"personId": 513525,
"timestamp": 1406222781,
"lastModified": 1406222781,
"code": "bPHbzaV7KsGWfuXJ",
"license": 1,
"width": 298,
"height": 232,
"flickrId": null,
"flickrOwner": null,
"_legacyUrl": "http://o.quizlet.com/ptqCa7LsKjiVSBVPI3OfTA.jpg",
"_legacyUrlSquare": "http://o.quizlet.com/ptqCa7LsKjiVSBVPI3OfTA_s.jpg",
"_legacyUrlSmall": "http://o.quizlet.com/ptqCa7LsKjiVSBVPI3OfTA_m.jpg",
"_secureLegacyUrl": "https://o.quizlet.com/ptqCa7LsKjiVSBVPI3OfTA.jpg",
"_secureLegacyUrlLarge": "https://o.quizlet.com/ptqCa7LsKjiVSBVPI3OfTA_b.jpg",
"_secureLegacyUrlSquare": "https://o.quizlet.com/ptqCa7LsKjiVSBVPI3OfTA_s.jpg",
"_secureLegacyUrlSmall": "https://o.quizlet.com/ptqCa7LsKjiVSBVPI3OfTA_m.jpg"
}]
},
"paging": {
"total": 50,
"page": 1,
"perPage": 2,
"token": "UuKKKAkmxv.r4YtwFDuRevZVGAHr"
}
}]
}

How to get data form airhob api ? My request is giving me a 401

I want to get flight informations from an Api called airhob(https://www.airhob.com/developers/api/docs).
To do that I´m using ReactJS and Axios to fetch data.
In the Api documentation, the header is only:
apikey – Your sandbox or production API key
mode - sandbox or production
Content-Type - application/json
So to do that, I write the following code :
var authOptions = {
method: 'post',
url: 'https://dev-sandbox-api.airhob.com/sandboxapi/flights/v1.3/search',
headers: {
'Content-Type' : 'application/json',
'apikey': 'MyApiKey',
'mode' : 'sandbox'
},
data:{
"TripType": "O",
"NoOfAdults": 1,
"NoOfChilds": 0,
"NoOfInfants": 0,
"ClassType": "Economy",
"OriginDestination": [
{ "Origin": "SFO",
"Destination": "LAX",
"TravelDate": "04/23/2018" }
],
"Currency": "USD"
},
json: true
};
return axios(authOptions)
.then(function(response){
console.log(response);
})
.catch(function(error){
console.log(error);
});
So the result for this code should display all flight to Los Angeles in my console.

NodeJS - Send JSON object parameters with node-fetch

I'm trying to create a webhook via the GitHub API. The docs say that I need to provide a config parameter, which should be an object, but I'm not sure how I can send a JSON in the URL parameters. Here's what I've tried:
fetch(`https://api.github.com/repos/${repo.full_name}/hooks?config={"url": "https://webhooks.example.com", "content_type": "json"}`, {
method: "POST",
headers: {
Accept: "application/vnd.github.v3+json",
Authorization: `token ${account.accessToken}`
}
});
and
fetch(`https://api.github.com/repos/${repo.full_name}/hooks?config.url=https://webhooks.example.com&config.content_type=json`, {
method: "POST",
headers: {
Accept: "application/vnd.github.v3+json",
Authorization: `token ${account.accessToken}`
}
});
They both result in the following error:
{
"message": "Validation Failed",
"errors": [
{
"resource": "Hook",
"code": "custom",
"message": "Config must contain URL for webhooks"
}
],
"documentation_url": "https://developer.github.com/v3/repos/hooks/#create-a-hook"
}
How do I properly send a JSON object? I'm looking for a solution using node-fetch
When you are doing a post request, it's implied that there will be a payload and the lib you are using will be expecting a body property containing your payload.
So just add
fetch('https://api.github.com/repos/${repo.full_name}/hooks', {
method: "POST",
headers: {
Accept: "application/vnd.github.v3+json",
Authorization: `token ${account.accessToken}`
},
body:JSON.stringify(yourJSON) //here this is how you send your datas
});
And node-fetch will send your body with your request.
If you want more details on that i'll expand my answer
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods here for a quick description of different http request type (verb)

AppSync HTTP Resolver IAM Authorization Error

I am trying to use http resolvers with AWS AppSync so that we can support using graphQL and our REST APIs simultaneously. I got the AppSync http resolver working when the API Gateway did not have any authorization setup on it. However, I've now locked down the gateway with IAM and I am trying to call it with the http resolver.
Using Axios, I am able to call the API Gateway with and I get a good 200 response with these params.
Request Params
{
"body": "{\"id\":1234}",
"data": "{\"id\":1234}",
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"x-amz-date": "20190209T101242Z",
"X-Amz-Security-Token": "AgoGb3JpZ2luEF4aCXVzLWVhc3QtMSKAAh9+SISFQH3bbHNLD47h5yCUsPmQhQ4Td74A1HmI/2jSu/Mg8mvK5IiMAMAMXokFQF8hZfzqsjfNWs+GcYkDRqhJbk7uaEaZFpjn5urgDAKVP/m5gywvnLnMWUXSOxTKe0kX+wTwHgnrV1wKR4+Fo97ykZPDasOPddw7HzSr9i2xKlKWEFB5iliZ08zvvA1OKUQ9gNdv6i+Cfwph/XGt0J7xvFtuYfOyZ5QRlyzggjS9cYbdaQ05A5vd+vAuDsdM7WXrU4OFN1ykRyw29VJU6eGFZTmBDX1AH7qI44ggjvwPOVUC/syAktuHgqqrADjleGdkRj0jZ+VoCybxAQYJEAQqpgUIcxAAGgw0OTc5OTY0NTMyNDgiDM9ufuhpC5ebbAUHHiqDBQ8P5DRX/leNqZEVIfcGahfFH6QfK9GZYDyW7iAVxHTEAL0ebMKi4Xo+vfatiISGgbTJuSB/csXvECTFkkuU1TNK21knO/WD5dWIIcKTSdQjZITMMtvTWk5JQWCFPrJ6ya6WENME3aYhfxXdCMuyL0EyFhx7A2J+GfukovfLRIU/CJl6GsyxSz0twNdBB71m7izPQ3rjN0ihNNayLWAfLhcU93Zq38BSavIesLYvqCpSYFH0fXrzhYaS+PRgKpvhgyR0r495OIIJfmSrMUZ2JZ/ct6YXanZCbEcFEwk91KPQDuG/NZhZcLpSPafU/HqkvaZ6gHSUpAR3jAi6XpLpaXHKS0vQnWV1ORnuIS/j9piDKe3HD42PsII9vgB69fZJK7wHImrqWwo9iKgHpiAYpJhs9K7lcznZ440NpjcA7VMBGBrvpFnLLv/VhTLVsYdNAeVfXMBshhEVsFVHvQstE/PHVvPTNMbk1eQwObKpQ/nprABPc4xWSKeF8w9TggwBrxemkDv+P0LhWqGso6WRssLH3GoKRE9znEawhvlxIbtDGJI38/j++zRTcreuduwbD29t+1pEk/5KJAnyxcQZmzTPlPTCA/TgRkeCEcOn7Xx/OZnG5137yK65xvHb2n1tPJsIDOlsD0AFP6me21sNkl5R4me746CR3ki0XUdIh4hPocKvlW+g32uWGBd6PMe+YwrCq8mD0NMxK3kgNMBtzX5IAyw51VTOIr01xCWrSegRbBtflYRtyHee2js3gu9N3ZfGHX13MDwvZi1WCfTDx3eP6wuPM4qcnJF/WBbkRU16PH8/Agkgxt5fQ4yaOOPv38GD1TRkGvWyshE2DJCilw27Qm8wms/64gU=",
"Authorization": "AWS4-HMAC-SHA256 Credential=ASIAXH4XG2WACM4YOUAC/20190209/us-east-1/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-security-token, Signature=3b72f69aa94fe41026a7d8806cccfe50dd24b247df6681065435f7eba135d02e"
},
"method": "POST",
"path": "/Prod/test",
"url": "https://q1gyu9a0he.execute-api.us-east-1.amazonaws.com/Prod/test"
}
Response
{
"data": "Hello from Lambda!",
"status": 200,
"statusText": "OK",
"headers": {
"content-type": "application/json"
},
"config": {
"transformRequest": {},
"transformResponse": {},
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json; charset=UTF-8",
"x-amz-date": "20190209T101418Z",
"X-Amz-Security-Token": "AgoGb3JpZ2luEF4aCXVzLWVhc3QtMSKAAoEkajE677gfDz3UMEhI27lvIHgikCQIVivGmUBKwcIjfz+JH9z4ILd/HBp2i/fFwtOjUNpo0fFnJeN73QkY18BRdtuTwtbBmS0B+kcOIvkaZnNMVEinUFIANxRxvhLET7koVenwtsGY+Tppv5NaUPNw5RERr1pzCO7HgeiQixG2rToTrqsiYCNLvTHTuojHSHZpISXdpV7vusWzjFJTQgR+sSvo9kjNYUBzbLCCBxmVv0KFzEf8dzxUEP2N92aExKW7cq98wakh440vt3gfpkG7Yg/wkGmABnwSgUlP2IVF7717oN7yoTlFFul1EDUwJs/VvWkueGUnfKRMKXkGg74qpgUIcxAAGgw0OTc5OTY0NTMyNDgiDN9R1UCNsLAVF3x6lyqDBXcq3VNhWLCYe8jpUgM2j9AMzyK6eS7LBAgaAYQiisdcFSVmMDIYL2AeMzgX/76UjaA73MFOKPmfBR4hrzk0wnwOjpz/FlLwU47teaqtjZZoxlTtk8X7xLj7wk5j6XnLRRjpOBXmVytEzTst4yKnFxFR2PDACFZfuPF+VPWPEttJ3eGuDAPITQPXvRUnpc+kl04BZsb72w31zP7kFl1EQqabJpz2ie41ObQbp4DZ9XhSzWrQvrovnu/mG0m6cWJeXG03Xee7SHmAVMAsvrpZ0OeBFl4nY4HM8L2SHiivwX/NnAkrrKxjO07ARunp4k30jxkZi0xQISp0qowboovVP0uPwQTwDty4FaT2EN+5CqJVqXGLioKo2GG1wjCAwinUcYt8iCq1A1lcTf2boYEjqmZyJ0apQAsNeD/wa0dqfKM5BwBz4G/JyxDo/tvtJ93RlcKg4rhaEf0NvsFvoHve0sUNJXh/LsGK4aZpkNS3Kbgrc8PZ2CsYADRW7b5V8uk8WAQ207SRHi8SUXWlDp9dYLgsQ2AUiUwel5Ph2iyKWxAVZ+h32Wmx6W2PJ8L9jWZsdmH7DYFwpWHpn8GmicXkSdVXnLD6WwaVtvDRjr8CKNrY/HZvyxU7zrRKFX141pEhEyzmyNboUR1XFRXvSnCoRxtBbIGgsTLjEpcdpCKWrwxplPVMY1MI/oD4waFJrJaO78VOy/2h0FylwaI4PVONgSkw2VWk4dD0Okr71Jx9A2h1P4zC3PnyUc6rfj5sk8ZabYShuY3WTIjW+j4j8ApEdjEAv8uguEoF9t4F4/3gt0g/0WAU1wX5kNGfpphpmeE6Do0rPCdlW3JDqNiZ7arsrAFgRSIw+s/64gU=",
"Authorization": "AWS4-HMAC-SHA256 Credential=ASIAXH4XG2WAC2MDEECX/20190209/us-east-1/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-security-token, Signature=664af118dadc082a7fa72a7e51266c2e42fcd3a4a83813032087898490a3eeca"
},
"method": "post",
"body": "{\"id\":1234}",
"data": "{\"id\":1234}",
"path": "/Prod/test",
"url": "https://q1gyu9a0he.execute-api.us-east-1.amazonaws.com/Prod/test"
},
"request": {}
}
Using AppSync with the following http resolver request mapping template, I am able to call the API Gateway as long as it is not configured to authorize with IAM.
HTTP Resolver Request Mapping Template
{
"version": "2018-05-29",
"method": "POST",
## E.G. if full path is https://api.xxxxxxxxx.com/posts then resourcePath would be /posts **
"resourcePath": "/Prod/test",
"params":{
"body":$util.toJson($ctx.args)
}
}
Working Response
{
"data": {
"test": "Hello from Lambda!"
}
}
Now I'm trying to call the API Gateway with the http resolver after I lock down the gateway with IAM. I use the following request mapping template to try and pass the fields and headers required, but I get an error. Not really sure where to go from here.
Request Mapping Template Trying for IAM
{
"version": "2018-05-29",
"method": "POST",
## E.G. if full path is https://api.xxxxxxxxx.com/posts then resourcePath would be /posts **
"resourcePath": "/Prod/test",
"params":{
"body":$util.toJson($ctx.args),
"headers":{
"Authorization": "$ctx.request.headers.httpAuth",
"Content-Type": "$ctx.request.headers.conType",
"X-Amz-Security-Token": "$ctx.request.headers.secToken",
"x-amz-date": "$ctx.request.headers.newDate"
}
}
}
Error Received
"{message=The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
The Canonical String for this request should have been
'POST
/Prod/test
content-type:application/json; charset=UTF-8
host:q1gyu9a0he.execute-api.us-east-1.amazonaws.com
x-amz-date:20190209T103353Z
x-amz-security-token:AgoGb3JpZ2luEF4aCXVzLWVhc3QtMSKAAi+vyglsAoh1DSzupAqx2f+vbwUM9PicHyM3p8IHX5VG3rZqH4sGlAu8SsAWtnmHeqYdjoQ7CESKAr9qjL7Vg07ooYnGNeuoHA4hiZghN9Y6iFOVcM2zA7bTGTN2RCmxYsJZ965dX1N0BpvvUcN6fDr8PP7Zoo1crt0e4DD3N/4yjZNYcor1sv58fkicTRTwQp5CYtVn5nQ9vsLg+4QW1btsKIhjsbgRYXGhD2kmJc8nhQvPJp9wq0AlL4FjECToWE7Gpo/C358sQvOHBqbxrFqduAIi4eCW8yrJQ9Az17BB0FlyvUpPAwDsWDprB3AvIZnFIDnZAjNv1bjY+OxCyqkqpgUIdBAAGgw0OTc5OTY0NTMyNDgiDE7sXyPsvDNEdskDXiqDBYgF4RTqVkYl5HJv+W8hk3VPMaMPkiEgpOvfryaDgN94rfr2RjNDnQA/r9QrL1TLn8SYG5v0IMnpW1jEUUN4PVxZUL/LB/8UpaMUCbviMy0Mz8e3PdOPpMShCbkL/iMS8jxOWXNgN3Y0Pjr2sivkndTpuIV44JvMG2UON57Vxxjl55KS7FT2jQMIBx7FAGe8nwYY/hYdl6dbzudHIjZuofOWjr5KPaAS38FTyXQGcqo+SaQHHDd9gUnYhRwtHy9pepPFwPY9BGJzW2hnS54jYixaZnwf+wewyALkXi3t749jPVDk0jyXMHgO57lK8lqqL3GL9GxQEMq0Ebga3nUuL8tuOLlOU5qrvS6l0fiTUkOZuwX2/Tkr6dc3cn12m9L3aNfg0UlAO2cR1ginMux6HIwmaeh2ycbmbR2zWd6ObRjDTc573zzX5x/sXkMWkOunR7B7NtAnMlbcNzQmf7KlAVzaP2f42V2e1HGjyJLHhCqGV9alf8Nj+BKi4njIZQHb/KxnmnZ+ZJcyn0DVtvFM+h/0eylAVXFwQh8TP7rVNsI72gtxiC39mWdJ7xKoqbX1jSjfjE8JBej2SEbYrXI/m2043Mv02sfgzHcOWDl7NFw+7zGScwVSBjkEYL8f55U1HbRrP1CuJYo7OlL8Y/0KxttfK6vPK7BLUAe9UpT0Yzh7Fz/5OXDs7n9s94iHRhOFj038akBB/Ye2v5fBEkPBbmGelD+7CGVNmMKgpnqHlzNpm3q3Gu2tcElSuF/3kUm4Eg0ElJbsRDEnsy5qhWt1fpeBrscpsfyifnZZOHL7enen0cK/iJY8SeJFnImj6eNhL/ymOrV1Sls90JF89F3tZfUvAGkwkdn64gU=
content-type;host;x-amz-date;x-amz-security-token
583ff6a2cabb532c16553f12958ec329caf1fe48d171d529b5e144f7a2c3f8f5'
The String-to-Sign should have been
'AWS4-HMAC-SHA256
20190209T103353Z
20190209/us-east-1/execute-api/aws4_request
2dcd7c552c2fec47b88e6f7d711b9a61879d8a12fc327a1a3f327287405ca0e5'
}"
AppSync can also compute the sigv4 signature required by Api Gateway on your behalf if you are using HTTP resolvers.
The configuration changes to your HTTP data source are not available through the console but using the AWS CLI you can pass the following paramaters:
aws appsync update-data-source --api-id yojcj4cdzzhizkscqocnr5xhem --name ApiGatewayTest --type HTTP --service-role-arn arn:aws:iam::769682826941:role/ApiGatewayRole --http-config file:///home/yourdir/apigateway.json
and the json file containing:
{
"endpoint": "https://apigateway.us-east-1.amazonaws.com/",
"authorizationConfig": {
"authorizationType": "AWS_IAM",
"awsIamConfig": {
"signingRegion": "us-east-1",
"signingServiceName": "apigateway"
}
}
}
AppSync does assume role on the role you provide, so it needs to allow AppSync to assume the role and call your API Gateway API.
You can find more info about the headers API Gateway expects in their documentation, here:
https://docs.aws.amazon.com/apigateway/api-reference/signing-requests/

github says cannot parse json while creating a repo in rest api

I'm learning REST api for github and trying to create a new repository by running a JS. Here is my function for creating a new repo: the token is generated, and all access/scopes is granted for my token.
function createNewRepo(userId, name){
var options = {
url: urlRoot + "/user/repos",
method: 'POST',
headers: {
"User-Agent": "EnableIssues",
"content-type": "application/json",
"Authorization": token,
"name": name,
"description": "This is repo creating by REST",
"homepage": "https://github.com",
"private": false,
"has_issues": true,
"has_projects": true,
"has_wiki": true,
}
};
//console.log(eval(options));
request(options, function (error, response, body)
{
var obj = JSON.parse(body);
console.log( obj );
});
}
however when running this, I find,
{ message: 'Problems parsing JSON', documentation_url: 'https://developer.github.com/v3' }
I'm not sure how exactly could the JSON be invalid.
Also, the documentation says it must include public_repo or repo which I'm also not sure how to apply here.
This for me has created the repository.
var myToken = "token INSERTHERETHETOKEN"; // <-- there must be the word token before the actual token.
var urlRoot = "https://api.github.com";
var request = require("request");
function createNewRepo(user, name, token){
var options = {
url: urlRoot + "/user/repos",
method: 'POST',
headers: {
"User-Agent": user,
// "content-type": "application/json", This is set by json:true
"Authorization": token,
"Accept": "application/vnd.github.v3+json"
},
body: {
"name": name,
"description": "This is repo creating by REST",
"homepage": "https://github.com",
"private": false,
"has_issues": true,
"has_projects": true,
"has_wiki": true
},
json: true
};
request(options, function (error, response, body) {
// Do your stuff... but notice that response
// is already a json object and you don't need to parse it.
});
}
createNewRepo("YourGithubUser", "test.repository", myToken);

Categories

Resources