Unexpected token in express ratelimit message - javascript

I'm using the package express-rate-limit to limit my express API requests. I'm using Pug for my client. Everything works fine, but whenever the ratelimit is triggered, I get the expected POST: 429 error, but then this error:
Uncaught (in promise) SyntaxError: Unexpected token 'Y', "You can li"... is not valid JSON
This is in relation to by express ratelimit message parameter:
const addLikeLimiter = rateLimit({
windowMs: 1000, // 1 second
max: 1, //Limit 1 like per one second
message: 'You can like once per second.',
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
})
app.use('/api/like', addLikeLimiter)
Is there any way I can fix this? I'm not sure why I'm getting this error.

This kind of error will come when we send a request in string format or send a response in string format server expecting a JSON string.
while sending the request body to the express server we will use
app.use(express.json()) //if its not there add this one
by default also we can set the response header JSON
res.setHeader('Content-Type', 'application/json');
or another way I think we can solve this problem send JSON output to the server
const addLikeLimiter = rateLimit({
windowMs: 1000,
max: 1,
standardHeaders: true,
legacyHeaders: false,
handler: function (req, res /*next*/) {
return res.status(429).json({
error: 'You sent too many requests. Please wait a while then try again',
});
},
});
app.use('/api/like', addLikeLimiter);

Related

post route for login page is pending request in browser with express node js

The router is pending not responding (pending in request)
router.post('/loginpost',(req,res,next)=>{
var email=req.body.email;
var password=req.body.password;
var selectsql=`SELECT * FROM client WHERE email='${email}' AND password='${password}'`
database.query(selectsql, (err,data)=>{
if (data.length>0){
req.session.email=email
res.json({datalogin:'success'})
res.end()
}
})
})
If data.length > 0 isn't true, then you never call res.json() so you never send a response.
Either:
You have an error
The credentials you sent are wrong
You don't have a body parsing middleware capable of handling the format of the data you are sending
You need to:
Test for err in case there is an error condition
Handle the case where isn't exactly one match (e.g. when the username and password are wrong)
and do some debugging to figure out which of the three failure states I listed above is the one you are triggering.

Unexpected token O in JSON at position 0 when I query an API

I know that the question is findable on the forum but no answer works for me. I have an angular service that calls a nodeJS API like this:
Angular service
public createUser(pUser: User): Observable<User> {
var url = "http://localhost:5000/users";
var json = JSON.stringify(pUser)
return this.http.post<User>(url, pUser)
}
NodeJS API
router.post('/', (req, res) => {
console.log(req.body)
User.create({ email: req.body.email, password: req.body.password })
res.sendStatus(200);
});
The API is well called, the insertion into database works, but I have this message in the browser:
SyntaxError: Unexpected token O in JSON at position 0
The status of the request is 200 on return but the error is still present in the browser
I do not know if the problem comes from the front end or the backend.
After doing some research, I try to parse my object before sending it. I try to stringify too.
Without success
Is this someone would have the solution? thank you very much
This error occurs when you try to parse invalid JSON.
Due to the default response type for angular is JSON and the default response of code 200 is 'OK'. You have to adapt one of them.
You can change the response type to text like this:
this.http.post<User>(url, pUser, {responseType: 'text'});
Or you return a JSON object:
res.status(200).send({ status: 'OK'});
It is good practise to send status 204 (No Content) if You don't send any content in response:
res.sendStatus(204);
Your Angular App should handle it and will not throw an error.
If You send status 200, it's good to add some json object, e.g. {status: "OK"} in res.status(200).send({status: "OK"}). Otherwise You will send the string 'OK' and will get "Unexpected token O ..." (O from 'OK').
From Express doc:
res.sendStatus(200) // equivalent to res.status(200).send('OK')

Is this a correct way to parse incoming JSON over websocket, and respond depending on the type of message?

So I am receiving JSON over a websocket from a chargepoint using OCPP 1.6 JSON.
I am trying to parse the message and respond appropriately, depending on what the message is, using Node.js
Here is the message that I recieve:
[ 2,
'bc7MRxWrWFnfQzepuhKSsevqXEqheQSqMcu3',
'BootNotification',
{ chargePointVendor: 'AVT-Company',
chargePointModel: 'AVT-Express',
chargePointSerialNumber: 'avt.001.13.1',
chargeBoxSerialNumber: 'avt.001.13.1.01',
firmwareVersion: '0.9.87',
iccid: '',
imsi: '',
meterType: 'AVT NQC-ACDC',
meterSerialNumber: 'avt.001.13.1.01' } ]
In this case it is the 'BootNotification' message, to which I need to respond with an 'Accepted' message.
Here is my code:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
//Make incoming JSON into javascript object
var msg = JSON.parse(message)
// Print whole message to console
console.log(msg)
// Print only message type to console. For example BootNotification, Heartbeat etc...
console.log("Message type: " + msg[2])
// Send response depending on what the message type is
if (msg[2] === "BootNotification") {
//Send correct response
} // Add all the message types
});
});
With this I get the message type printed to the console as a string:
Message type: BootNotification
So my question is that is this the correct way to get the type of the message?
I am new to this so I want to make sure.
The specification for OCPP 1.6 JSON is available here: OpenChargeAlliance website
I guess YES. JSON.parse is the built-in to, well, pares JSON strings. In case that goes wrong it throws an error, so you might try/catch this.
Since the response you get is an array, there is no other way as to access its items with a numeric index.
In such cases I personally prefer to have something like that:
const handlers = {
'BootNotification': request => { 'msg': 'what a request' }
};
Than you can:
let respone = {'msg': 'Cannot handle this'}
if (handlers.hasOwnProperty(msg[2])) {
response = handlers[msg[2]](msg);
}
But that is just the way I would go.
If you are asking about OCPP message structure (not parsing a JSON), I can provide you the details about OCPP 1.6 version.
In OCPP 1.6, the client (Charging Station) sends a CALL (similar to request in HTTP) to server (Charging Station Management Systems). All CALLs have a strict structure of 4 elements:
MessageTypeId (integer)
UniqueId (UUID, string)
Action (string)
Payload (JSON object containing the arguments relevant to the Action.)
or as in your example:
[
2,
'bc7MRxWrWFnfQzepuhKSsevqXEqheQSqMcu3',
'BootNotification',
{ chargePointVendor: 'AVT-Company',
chargePointModel: 'AVT-Express',
chargePointSerialNumber: 'avt.001.13.1',
chargeBoxSerialNumber: 'avt.001.13.1.01',
firmwareVersion: '0.9.87',
iccid: '',
imsi: '',
meterType: 'AVT NQC-ACDC',
meterSerialNumber: 'avt.001.13.1.01' }
]
So the Type of Action should be always at index of 2 (as you retrieve it when you parse received message). You can refer to #philipp anwser on way how to handle an errors when parsing.

Swagger codegen generated client access control issue

I have generated a client side app with swagger codegen for a specific API, the javascript version. Initialized it with npm etc. etc. everything claps.
However when i try to send a get request with the generated api from my localhost to http://81.2.241.234:8080/species i get the following error:
Error: Request has been terminated
Possible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.
at Request.crossDomainError (bundle.js:2967)
at XMLHttpRequest.xhr.onreadystatechange (bundle.js:3049)
The mentioned headers are present on the servers response if i call the url from chrome.
Some code for easier understanding:
var speciesApiInstance = new index.SpeciesServiceApi();
var opts = {
'start': 0, // Number | start position
'count': 10, // Number | count
'orderfield': "name", // String | order by
'orderdirection': "ASC" // String | order direction
};
var callback = function(error, data, response) {
if (error) {
console.error(error);
} else {
console.log('API called successfully. Returned data: ' + data);
}
};
speciesApiInstance.getSpecies(opts, callback);
What am I doing wrong? Couldn't find an answer in the docs.
Solution: I was using HTTPS connection, the mentioned IP connects with http only, thus the preflight request failed. Modified the connection url to call the API with http and it works properly.

Getstream.io "Not authenticated" with read only token

I am using the django getstream.io client. My backend code looks like the following, it generates a read-only token and stores it in the response with my jwt token that is sent on a successful login. This code is at the bottom of my settings.py file, which contains the STREAM_API_SECRET, and STREAM_API_KEY key settings. These are also in my settings.py and match what is in my getstream.io dashboard.
from stream_django.client import stream_client
def jwt_response_payload_handler(token, user=None, request=None):
user_feed_1 = stream_client.feed('user', str(user.id))
readonly_token = user_feed_1.get_readonly_token()
return {
'token': token,
'stream': str(readonly_token)
}
On the frontend, the token is correctly gotten from the login response, which contains the stream token. It attempts to setup a real time stream, but when it connects i get a "Not authenticated error". I have confirmed, that the token passed to the following client side function, matches the token generated above.
function setupStream (token, id) {
var client = stream.connect(STREAM_API_KEY, null, STREAM_APP_ID)
var user1 = client.feed('user', id, token)
function callback (data) {
console.log(data)
}
function failCallback (data) {
alert('something went wrong, check the console logs')
console.log(data)
}
user1.subscribe(callback).then(() => {}, failCallback)
}
I am not sure what I am doing wrong because as far as I can tell everything is setup correctly. The tokens, and user id's match what is on the front and backend.
I am following what is in the documentation, but its not working:
https://getstream.io/docs/#readonly-tokens
When i tried just the following in console:
user1.get({ limit: 5, offset: 0 })
.then(callback)
.catch(failCallback)
The exact error response body i get from that is:
{
"code": null,
"detail": "url signature missing or invalid",
"duration": "7ms",
"exception": "AuthenticationFailed",
"status_code": 403
}
EDIT:
it seems by changing:
get_readonly_token() to .token, creating a read/write token, the client side code works. Does readonly token not work?
so it turns out, I am decoding the read_only token incorrectly. Changing the backend code to the following solved my issues;
'stream': readonly_token.decode("utf-8")

Categories

Resources