Express HTTP Only Cookie issues - javascript

Here is the request being made to the api.website.api server from website.app.
website.app has a http secure cookie
I'm assuming the http cookie is being sent along in the request?
axios.get('api.website.app/route',{withCredentials: true}).then(res => {
// some code
})
In an auth middleware function, I call req.cookies.access_token but it's not being verified on the request. It seems the server isn't getting the cookie from the http request. I'm trying to get the server to verify the token but it's not doing so.
This is the middleware function I am using
The route in express using the auth middleware.

Related

What’s the difference between res.send and app.post?

I’m new to express and HTTP. The express library has app.get, app.post and res.send. As I understand it, app.get uses/is used with GET and app.post POST. Does res.send call POST?
res.send() sends a response to an incoming http request that has come into your http server.
app.post() registers a request handler with Express for a specific URL in your http server and for POST requests so that when your Express server receives a POST request at that URL, it will call this request handler.
Here's an example of res.send():
// configure request handler for GET request to /
app.get("/", (req, res) => {
res.send("hi"); // send response to incoming http request
});
Here's an example of app.post():
// this middleware reads and parses the body for content-type
// of application/x-www-form-urlencoded
app.use(express.urlencoded({extended: true}));
// configure request handler for POST request to /login
app.post("/login", (req, res) => {
// in a real request handler, this would be some sort of username
// and password comparison in a database and using appropriate crypto
if (req.body.username === "John" && req.body.password === "foobar99") {
res.send("login successful");
} else {
res.status(401).send("Login failed");
}
});
The express library has res.get and res.send. As I understand it, res.get uses / is used with GET.
You are perhaps confused because there is no res.get. Perhaps you meant app.get()? If so, app.get() configures a request handler for an http GET request to a specific URL. So, app.get("/books", ...) might display a page of all available books.
Does res.send call POST?
No. res.send() sends a response to an http request.
Here are the steps you can think of.
An http client (such as a browser or any piece of code) creates an http request and sends that request to a server.
That request will have both an HTTP verb such as GET, POST, PATCH, etc... and it will have a URL such as /login or /books.
The web server that the request was sent to receives that request. In the case of a web server using the Express framework, the Express server looks through its list of already registered routes (these routes were previously registered with app.get(...), app.post(...), app.use(...), etc... These are essentially listeners for specific routes. If the Express server finds an already registered route that matches both the http request verb and the URL, then it calls that route handler and pass it three arguments (req, res, next).
When the request handler code gets called, it can examine the req object to see any data about the incoming request such as the exact URL, any http headers on the request and so on. It can use the res object for sending a response such as setting any http headers on the response, setting content-type, setting an http status code for the response, creating and sending the body of the response, etc... res.send() is one way to send the response. There are also others such as res.sendFile(), res.json(), res.sendStatus() and so on...
After one of these methods is called that sends the response, then the underlying engine sends that http response back to the client that sent the original http request and the HTTP request/response is considered complete.
Those are two different modules/objects..
The Express Router supports HTTP methods for the server to listens and respond to - .get(), .post(), .put().
One of the arguments passed through the chain of middleware and handlers is the Response, which has a .send() method to send its response back to the client. The Response object can also be enhanced to send JSON, etc.

res.send token and then redirect

I have an express app that upon calling a get request immediately returns a string token, then runs a python code. The python code after some time creates a json file that I need to send in another post request.
This python code may be called by different users that's why i need to assign them a token a soon as the app is called.
In the post request i'll also be modifying the json file and then sending it back
I'm trying to do res.send the token and then res.redirect to the post request, but i know it's impossible. Is there any other way i could send the token or redirect to the post request?
app.get('/', (req, res) =>{
res.send(token())
runPython((code)=>{
*takes around 10 sec*
res.redirect('/post')}}
app.post('/post', (req, res)=>{
*do stuff to file*
res.sendFile()
You cannot send multiple responses back to the client separated in time. You get ONE http response. So, once you've done res.send(token()), then that http request is done. You can't send any more data as part of that http request.
As you describe things, here are some of your options:
Combine both into one response. Wait to send the token until you have the python response too and then send them both in one JSON response. You won't be able to do a res.redirect() if you're also sending data back. So, you could send the redirect location back in the JSON and have the client manually do the redirect (by just setting window.location to a new URL). Presumably, there is client-side Javascript on the receiving end of this anyway since some form of code has to receive the token anyway to do something useful with it.
Use websocket/socket.io connection for subsequent server-initiated communication. Have the client connect a webSocket or socket.io connection. You can then response with the token and then later when the python has finished, you can send additional data over the websocket or socket.io connection. This will require additional code to be able to associate a particular websocket/socket.io connection with the client that made this request so you can tell which websocket/socket.io connection for this request to send a notification over.
Client-side polling for completion of python operation. Have the server send back the token and also send it some sort of request ID and then the client can poll the server every few seconds to ask the server if that python operation for that request ID is now done. When it gets a response from the server that the python is now done, then the client can manually redirect itself to /post to fetch the final data.

A cookie not in document.cookie list while http_only = false

I have a Nuxt.js frontend application, which performs an authentication request. There is a Laravel/Sanctum application on the backend. It uses built-in cookie-based session authentication. The authentication request fails because no X-XSRF-TOKEN HTTP header is provided in the /login request. Can anybody help to clarify why the header is not created from the cookie provided by the backend?
Note: Everything works properly on my laptop. It fails only when deployed to test enveronment (GCP VM instance + Gitlab Pages).
Auth code in Nuxt.js:
this.$axios.defaults.withCredentials = true; await
this.$axios.get("/sanctum/csrf-cookie");
console.log(document.cookie);
await this.$axios.post("/login", credentials);
I can see that XSRF-TOKEN cookie is returned by server
I also see that the XSRF-TOKEN cookie is provided in the /login POST request, while no X-XSRF-TOKEN HTTP header is created
Cookie details
I also debuged the axios source code and see the it tries to create X-XSRF-TOKEN header taking the XSRF token from the document.cookie. But document.cookie doesn't contain the token cookie as of that moment. Why?
I have found the reason. The session domain was incorrect. I have set .my-domain.co.uk and it works now.

Can´t make POST request from VUE to ESP32 https server

I´m trying to make a POST request from a vue web app to a ESP32 https server.
The request is always blocked by CORS because self-signed certificates.
ESP32 Starts in AP mode, generating his own Wifi network.
An https server, with SSL certificates generated by me, starts running (using this library: https://github.com/fhessel/esp32_https_server)
In a PC running locally the VUE app, I make the POST request to the ESP32 server (see code below)
(I´m using axios to make the request)
I have tried:
Adding a custom https aggent with rejectUnauthorized:
Adding same cert in POST request that ESP32 server uses
Adding CORS headers
Adding process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
Starting vue dev server in https mode with ESP32 same certs
Try to obtain the OPTIONS request in ESP32 server to allow the POST request
Making the request with curl or postman works fine!! It´s like a problem with the browser or vue.
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
axios.post(`https://192.168.4.1/config?ssid=${this.ssid}&ssidkey=${this.password}`, { httpsAgent })
.then((res) => {
...
});
The goal is to configure my WiFi credentials by conecting directly to the ESP32 in AP Mode first.
If I use curl or Postman to make the request its working fine, the ESP32 receive WiFi credentials and connect to my router, but it has been impossible to me to make the same with the vue web app...
You can find the full details of how the CORS mechanism works on the mozilla developers page: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
In summary, the browser automatically performs an HTTP request with the method OPTIONS with the same url of your original request to your server, and this request can't be avoid. The browser expect that this request responds with a status 200 and with the CORS headers ( for example:
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
)
Once the response to the method OPTIONS is receive and looks valid for the browser, your original request is performed by the browser.
So, you need to configure your server to responde to the options method with the cors headers.

Add Request Variable from Client to NodeJS Server for MiddleWare Router

I am trying to use routes to help server pages from a nodejs server based on a user being logged in. I am trying to take the login session details from the client side, and pass them back to the NodeJS server to be used in a middleware function for checking authentication.
How do I go about adding a variable to a request for a NodeJS route from the client side?
middleware.js
function loginRequired(req, res, next) {
if (!req.user) {
return res.status(401).render("unauthenticated");
}
next();
}
module.exports = { loginRequired };
server.js
app.use("/dashboard", middleware.loginRequired, mainPage);
The desired result would be, user clicks "Login", some variables are sent back, as well as the request to that route, the variables (i.e req.user) are used to check authentication.
You can send the variables in cookies, and use cookie parser, before your middleware. It provides parsed cookies.
For example, you can send a User variable in cookie, and then in your middleware use req.cookies which will contain your User variable.
Alternatively, you can send data in a POST request and use body-parser to do the same thing. But for authentication purpose, you should use cookies.

Categories

Resources