500 error depending on data submitted in POST request - node.js

Setup: NodeJS / Express / Helmet API running on Azure App Service, CORS set to allow * so should be all fine.
Client web setup running locally on NodeJS (http://localhost:3000)
I'm trying to POST some JSON from the web client to the API for login validating purposes. Works for some requests and not others, seemingly depending on what actual values I am posting.
I've got a bit of code that uses the Fetch API to send login details and validate them, as follows:
const response = await fetch(`${baseUrl}/auth/validate`, {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({EmailAddress: email, Password: password}),
}).catch(error => {
alert('Unable to check login');
});
If the value of email and password are both just me leaning on the keyboard, say 'skdjflsjdf' then it's all fine - the server gets my POST, validates that the login is rubbish and bounces back my error. It allows it because I get the Access-Control-Allow-Origin: * header back, so Chrome is happy.
If the value of email is an actual email address, I don't get the Access-Control-Allow-Origin: * header back and Chrome gets very upset of course.
I can't even begin to imagine how I've gone wrong here and I certainly don't seem to be able to find the right phrase to Google for a sensible answer. I'd really appreciate any help... Thanks.

Related

How to send data (2 strings) from a next.js server to a node.js server and then update values on the node.js server with the new data

Apologies if I sound uneducated on the matter, I have never used JS until a few days ago and don't have much server/API experience.
Essentially I am using nextauth.js to authenticate a users twitter account and allow them to sign into an app. Next.js is providing them with a sign in option and once they sign in and authorize the app I now have access to their api key/ secret.
I also created an app in node.js that will allow me to change their twitter header for them. This runs on a separate port. I need to be able to send the key/secret I get from the next.js app to the node server so that I can use these keys to make the changes to their account. I am unsure of how to do this and what type of requests are required.
Ive spend a good amount of time looking into online resources but I haven't been able to conceptualize it fully. Any help/resources/explanations would be very appreciated! Thank you in advance!
if you have access to secret key you wanna send on the client-side you can simply use fetch
const response = await fetch('https://yourbackend.url/here', {
method: 'POST', // make sure the method is set to POST
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({secretKey: "yourseceretkeyhereaslkdaasldkaslkdjlask"}) // send the secret as payload in the body
}).then(res => res.json())
.catch(console.log);
catching the payload on your server will totally depend on what kind of server you have setup.

403 error with axios but works on postman and browser

I get Nfts on magic eden with this third party api.
http://api-mainnet.magiceden.io/rpc/getGlobalActivitiesByQuery?q=%7B%22%24match%22%3A%7B%22txType%22%3A%22initializeEscrow%22%2C%22blockTime%22%3A%7B%22%24gt%22%3A1643468983%7D%7D%2C%22%24sort%22%3A%7B%22blockTime%22%3A-1%7D%7D
It responses with results on postman and browser but causes 403 error with axios in node.js.
How can I get data in node.js?
const res = await axios.get(
'http://api-mainnet.magiceden.io/rpc/getGlobalActivitiesByQuery?q=%7B%22%24match%22%3A%7B%22txType%22%3A%22initializeEscrow%22%2C%22blockTime%22%3A%7B%22%24gt%22%3A1643468983%7D%7D%2C%22%24sort%22%3A%7B%22blockTime%22%3A-1%7D%7D',
{
headers : {
"Content-Type": "application/json",
"Access-Control-Allow-Credentials": "*"
}
}
);
return res.data;
Using a proxy here won't help as they have Cloudflare protection set up against bots/scripts and it requires cookies to be present: screenshot 1, screenshot 2
You should get in touch with their support and ask for the API key (they have a public API v2 coming soon), and then use it in Authorization: Bearer <token>
Few things to note here: Their API v2 is still in works and lacks some basic features. Using their current v1 API does not require having an API key (that's what their support personnel said) but it does have bot protection against scripted attacks.
I'm hesitant to go with the API v2 since it lacks even the most basic stuff and I don't expect it to come out anytime soon. Personally, I'm looking to get in touch with people who managed to integrate the v1 into their applications, to see what necessary steps they followed in order to be able to do it.
If you managed to find some new info on that regard let me know. I'll also edit this comment in case I find out how to set up the v1 connection properly.
EDIT: managed to get it working by using the https://github.com/puppeteer/puppeteer library. Started a small headless instance of Chrome and I hit the ME API with that browser like so: screenshot 3
It can be because of CORS error.
You can use Cors proxy to fix it.
Try it,please.
const CORS_PROXY_API = `https://cors.ryanking13.workers.dev/?u=`;
const magicedenAPI = `http://api-mainnet.magiceden.io/rpc/getGlobalActivitiesByQuery?q=%7B%22%24match%22%3A%7B%22txType%22%3A%22initializeEscrow%22%2C%22blockTime%22%3A%7B%22%24gt%22%3A1643468983%7D%7D%2C%22%24sort%22%3A%7B%22blockTime%22%3A-1%7D%7D`
const { data } = await axios({
method: 'get',
url: `${CORS_PROXY_API}${magicedenAPI}`
});

Axios library Adds additional "/" between my post request endpoint parameters

I've a piece of code that sends a post request to my backend. Everything works fine for me.
However I have a vendor that are overseas facing a weird error. When they render my Vue Web Application, the POST request made to my backend has an additional "/" in between the parameters.
And i really do not know why it keeps happening at their end but not on me. We are both using the same browser.
Below is the library and part of the code that makes a request to my backend.
import axios from "axios";
export const HTTP = axios.create({
baseURL: _baseURL,
headers: {
"Content-Type": "application/json",
'Accept': "application/json"
},
timeout: 30000
});
HTTP.post(
`/someotherparams/restapiparams/${this.someinput}/someparameter/${this.moreinput}`,
{
something: "some text"
})
At the Vendor's End when i check the network of the browser, it shows that it is firing the following :
"BaseUrl/someotherparams/restapiparams/${this.someinput}//someparameter/${this.moreinput}"
As you can see there's an additional "/". Advance thanks for some guidance.
Note*: I've check the codes many times, the data in the data base for the this.someinput (does not contain '/') values. It works well for me, it did occur once from my support team. but the vendor is facing this issue every time.

How to authorize for Amazon's Alexa API?

I want to send a request to this Amazon Alexa API.
That page contains the last 50 activities I made with my Amazon Echo. The page returns JSON. Before you can request that page, you need to authorize your account, so the proper cookies are set in your browser.
If I do something simple as:
const rp = require("request-promise");
const options = {
method: "GET",
uri: "https://alexa.amazon.com/api/activities?startTime=&size=50&offset=-1",
json: true
};
rp(options).then(function(data) {
console.log(data);
}).catch(function(err) {
console.log(err);
});
I can send a GET request to that URL. This works fine, except Amazon has no idea it's me who's sending the request, because I haven't authorized my NodeJS application.
I've successfully copied ~10 cookies from my regular browser into an incognito tab and authorized that way, so I know copying the cookies will work. After adding them all using tough-cookie, it didn't work, unfortunately. I still got redirected to the signin page (according to the error response).
How do I authorize for this API, so I can send my requests?
I have been looking for a solution for this too. The best idea I have is to use account linking, but I haven't try it yet. Looks like ASK-CLI has interface for this also, but I can't figure it out how to use it (what is that URL?). For linking account to 3rd party server is not easy, but link it back to Amazon for the json API should not be that complicated.

"Fetch failed loading" - fetch works in Postman but fails in Chrome & Safari

Update: Fixed. It looks like the request was coming back as a 503 (as it should), then my app refreshed and displayed the non-error message: "Fetch failed loading". I just wasn't seeing the response because of the refresh.
I am not able to make a fetch request from my locally-hosted Create-React-App to my Heroku-hosted Node server.
My Node server has CORS enabled. If I make a POST request via Postman, I get an appropriate response (503, because currently there is no database hooked up, so the data is not being saved. If I should be sending back a different response, let me know). My Postman request has 'application/json' as the content-type, no authorization, and a body of { "rating": "5", "zipcode": "0" }.
However, when I make a POST request from my React app, I get a message in my console: "Fetch failed loading: OPTIONS "https://shielded-gorge-69158.herokuapp.com/feedback"." There is no associated error, only the message. There is no information about the request in my Network panel.
The fetch request works when I do it locally, from localhost:3000 (my app) to localhost:5000 (my server). It only fails when I try to make the request to the (otherwise identical) server hosted on Heroku.
This is what the fetch request looks like:
return fetch('https://shielded-gorge-69158.herokuapp.com/feedback', {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({ rating: userRating, zipcode: userZip })
}).then(res => {
if (!res.ok) {
throw new Error('Error:', res.statusText);
}
return res;
}).catch(err => console.error(err));
Edit: I'm continuing to research and it seems like Postman shouldn't/doesn't make preflight requests (https://github.com/postmanlabs/postman-app-support/issues/2845). So perhaps that is the issue — but why would the request be working when my server is local, but not when it is hosted on Heroku?
use 'Content-Type' instead of 'Content-type'.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests
https://fetch.spec.whatwg.org/#cors-safelisted-request-header
Explanation: when you use incorrect case then it is considered as a custom header and hence, a preflight request is sent in such cases. Now if OPTIONS request is implemented on server with correct cors spec then next POST will be sent, else it wont be sent and request will fail. More on this in above links.

Resources