api design - How to design public POST api to prevent spam request - node.js

I am developing a public website
One of the page is to let people submit opinions.
They need to enter email, phone, message ,etc, in order to submit the opinion form.
This means I need to make an api for people, so that after they press the submit button, the POST request will be sent.
But some people might abuse this function(e.g. create bot to send massive amount of POST request).
Since the frontend design is already finished and no recapcha is used in frontend, I was thinking if there are backend ways to do it.
Is there any ways/best practice to prevent this kind of things?
I am using node.js(aws lambda) for my api function

Yes, if there is still a way to implement captchas, use package "svg-captcha". If you only want to deal with the backend, refer to this header: req.headers['user-agent'];, so you can track down those who abuse the requests and limit their access for a while.

Related

Discord API Rate Limiting

I am currently creating a web-dashboard for a Discord bot I have made previously.
I am using express.js as my backend server, and in order to validate user's credentials, almost every request made whether it is a get or post request, has some sort of call to the Discord API originating from the backend of the dashboard before the frontend is served to the user (as I do not know how I can securely make API requests from the frontend as user tokens are required)
As you can probably guess from the previous paragraph, I have been temporarily banned from using the API (below), meaning I can no longer use my Discord Account and my bot has gone offline.
Image showing API error (Code 429)
I understand that the API request sends headers regarding the rate limits and remaining quota etc, I just don't know what to do with that data. What would be the best programming practices in order to solve this rate-limiting issue?
I have tried using the refresh tokens initially, as I thought new tokens would stop users having to re-authenticate. These tokens were stored in a mongodb database (to prevent me from sending a token request every time a user wanted to make a request), but these measures did not help as much as I would have liked them to.
You shouldn't be experiencing rate limits that quickly, why are you making so many requests to the API? The access token provided from OAuth2 flow works for multiple requests (it stays valid for a full week if you don't ask for a new token), so make sure you aren't requesting a new token every time the client loads your app.
If the problem is that you're using the access token to make a request to the Discord API for user info every time the user reloads your app, then you need to change that. Just save user info on your backend, and every once in a while (maybe a minute or two), "refresh" their data automatically by making just one request. That way if somebody spam reloads your app, your app won't then spam request the Discord API for new info every time.
If you are ever ratelimited by Discord because your users spam reloaded your app, that's a vulnerability on your end and you need to handle it.
Also, you mentioned using the rate limiting info provided in the request headers. That info can be useful so that you know how long to wait before making another request, and stop Discord's API from acting up towards your app. But it definitely wouldn't help in actually stopping your app from getting ratelimited, that can only be helped by managing how you make requests to the Discord API better.

How to redirect react app to payment success page after completing payment by scanning a QR code?

I have a PERN(Postgres, Express, React, Node) e-commerce app. I want to notify a user that the payment is successful by redirecting to a payment successful page after a user scans QR code to pay.
However, I'm not sure how do I achieve this.
Currently, after the user completed a payment, I will receive a REST's POST request for payment confirmation from a bank API. . However, I'm also using GraphQL and I think that Graphql's Subscription could be what I'm trying to achieve.
Does anyone know how am I supposed to achieve this?
Are there anyways to send a request from REST to Graphql on my own server?
Or are there any better ways to do this?
Just like what is done in this video:
Do I understand correctly that you are looking for a way to notify your client that the payment was successful?
I assume you know how to handle redirect logic so here are the ways you can notify your web-app from the server.
1. Regular HTTP request
The client sends a regular HTTP-request to your server and you withhold the response until you received the 'payment completed' request from the bank API. If your request times out before the bank API confirms the payment - you simply send the same request again. This pattern is also known as Long Polling
2. Server-Sent Events
Your client can open a channel to your server that allow your server to send Events to your client (one-way). It is fairly easy to implement and a solid way to handle one-way communication. Check out the MDN documentation.
3. Web-Sockets MDN
You are probably familiar with these since they are the de-facto standard nowadays. Similar to Server-Sent Events but they allow two-way communication.
Most libraries that handle client-server communication implement a combination of these technologies in order to provide a fallback solution. I would recommend to stick to one of these libraries as they handle many edge-cases that are otherwise work-intensive to cover.
As you pointed out, if you are already using GraphQL you can simply use its subscriptions api. It uses WebSockets with a fallback to long-polling underneath.
Other popular options include socket.io or graphql-sse.

Caching response for API.ai Node.js webhook

I have a webhook designed in Node.js for API.ai that interacts with multiple API's to gather information and give response to user.
Since, I am interacting with multiple API's the response time taken is more than 5 secs which is causing the API.ai request to timeout.
To overcome this, I am trying to implement caching into the node.js webhook which saves the response from API's until a certain amount of time. This will remove timeout until the max-age header time is reached.
Edit: What is the best node module that I can use to cache the API responses for subsequest requests.
Note: I am using request node module for http requests but it doesnt seem to provide a way to cache the response.
All of the answers given are reasonable for tackling the cache problem on the request side. But since you specified API.AI and Actions, you might also be able to, or need to, store information while the conversation is in progress. You can do this using an API.AI context.
It may even be that if you limit it to just one remote call for each response from the user, you might be able to fit it in the timeframe.
For example, if you were having a conversation about movie times and ticket ordering, the conversation may go something like:
User: "I want to see a movie."
[You use an API to lookup the nearest theater, store the theater's location in a context and reply] "Your nearest theater is the Mall Megaplex. Are you interested in one there?"
User: "Sure"
[You now already have the theater, so you query for what it is playing with another API call and store it in a context] "There are seven different movies playing, including Star Wars and Jaws. Do those sound interesting?"
User: "No"
[You already have the data in the context, so you don't need another call.] "How about Rocky or..."
In this way you're making the same number of calls (generally), but storing the user's results in the session as you go as opposed to collecting all the information for the user, or all the possible results, and then narrowing them.
Finally decided to use the below module:
https://www.npmjs.com/package/memory-cache
This served my scenario better. Might try using Redis soon when i get some time.

Creating new payment method for Bigcommerce

I would like to know if this is possible to add new payment method for Bigcommerce. I tried to contact their support without any luck. If anyone is familiar with bigcommerce and know if this is possible, i would appreciate any advice.
I already read their API docs and didn't found anything useful - only method to obtain list of available payment methods.
I already tried to signup for their partner. Without any luck.
We've done this before for a couple stores to allow clients to process payments through their own processor. The way we achieved this, is essentially through the following high-level steps:
Allow payments by Check (or similar offline method). We are going to replace this with the custom processor.
You'll notice that if you attempt to checkout via Check, that BigCommerce automatically creates the order for you, but sets the order status to Awaiting Payment. Upon submission the user is automatically sent to a 'Thank You' Order Confirmation page that contains both the Order ID and some payment instructions (such as where to send the check to).
Here's the trick -- Modify this 'Order Thank You' page to prompt the user for her or his credit card information. A simple HTML form will suffice here, performing the actual request via JavaScript.
Once you have the user's credit card data, you can then POST it to your own external server, where you would connect to and send data to whichever processor you are using. Additionally, you should make sure to send the Order ID to this program, so that you can connect to the BigCommerce API to load billing information, and then subsequently adjust the order status to either approved or declined depending on the response from your processor. Finally, you should send back some sort of response to the client to inform of the result of the charge attempt.
That's pretty much it in a nutshell. The way you integrate with the payment processor (step 4) is unique to whichever processor you are using. I hope this makes sense.
Although opinion based, I'm a huge fan of serverless technologies, and would suggest looking into AWS Lambda + AWS API Gateway. The benefit here is that you don't need to worry about creating an infrastructure or the associated concerns of security and scale. Rather, AWS Lambda allows you to simply upload your software, and allows it to be executed via an HTTP request to some defined endpoint set through the API Gateway. Lambda will scale automatically for you, and you don't need to worry about system level security concerns - only security at the application level. It's truly a set and forget setup, and a bleeding edge technology. Not to mention dirt cheap!
Implementing a new payment method is unsupported and requires hacky workarounds since we implement payment gateways via the core app. You can do this on blueprint by using an offline payment method and then using the API to update payment statuses, etc. I'd recommend using ActiveMerchant if you do wish to go down this path.

How To Prevent GET Requests?

I am creating a site that will encourage users to visit again. Therefore, I'm afraid of people sending spam or bots to the site.
How can I block this type of spam? I've heard of spamming GET requests to make it look like there are more visits. What can I do to protect myself?
The main way to cut down on bot artificial traffic is to use a "captcha" image
look into reCaptcha or secureimage and integrate this. Whether you submit these methods via GET or POST, the captcha var will be checked on the server side at which point you can admit/deny for the purposes of averting bots.
Hope this helps.
R

Resources