I have an app with front end built in React and backend with NodeJS. My app is working fine when I run locally on my computer using local hosts. However, when I deployed my app on render.com, I'm facing an issue with my authentication header.
I login to app successfully, but after that to access APIs I have to use JWT. I receive the JWT after login and include it in my request to later APIs, but my server do not receive the authentication header. Following snapshot shows the problem:
However, on server side following header is received:
I've attached both screenshots from chrome developer options. Also below you can see snapshot for console for header received on server:
Reached verifyToken with token: {"host":"nearusnewadminserver.onrender.com","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36","accept":"/","accept-encoding":"gzip, br","accept-language":"en-US,en;q=0.9,ur-PK;q=0.8,ur;q=0.7,fa-IR;q=0.6,fa;q=0.5,ar-AE;q=0.4,ar;q=0.3","access-control-request-headers":"authorization","access-control-request-method":"GET","cdn-loop":"cloudflare; loops=1; subreqs=1","cf-connecting-ip":"185.67.127.180","cf-ew-via":"15","cf-ipcountry":"GB","cf-ray":"8be10f90528977a5-LHR","cf-visitor":"{"scheme":"https"}","cf-worker":"onrender.com","origin":"http://localhost:8000","priority":"u=1, i","referer":"http://localhost:8000/","render-proxy-ttl":"4","rndr-id":"d77239b2-95cc-481b","sec-fetch-dest":"empty","sec-fetch-mode":"cors","sec-fetch-site":"cross-site","true-client-ip":"185.67.127.180","x-forwarded-for":"185.67.127.180, 10.222.42.14, 10.223.245.2","x-forwarded-proto":"https","x-request-start":"1725485217438628"}
Note that I had to add following middleware to my backend as my front end host and backend host are different on render.com: (In below snapshot I used my dev-server host url as I'm testing with it to make sure header is included.
function accessControl(req,res,next){
console.log(`Reached access control allow part`);
res.setHeader("Access-Control-Allow-Origin", "http://localhost:8000");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
next();
}
module.exports = {
accessControl
}
I have searched many forums but couldn't find the solution. It is also worth noting that when I send the same request with Postman it works fine.
It looks like you have a CORS error in the browser console because the options request failed.
Please check how it's implemented in cors lib https://github.com/expressjs/cors/blob/master/lib/index.js#L159 Firstly you need to handle Options request and send successful response. You forgot about Access-Control-Allow-Methods.
I recommend you to use this lib instead of yours uncompleted solution https://www.npmjs.com/package/cors Example:
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors({
origin: ["http://localhost:8000"],
}))
app.get('/countries', function (req, res, next) {
res.json(['US']);
})
app.listen(80, function () {
console.log('server listening')
})
Provide the code how you are using this accessControl middleware. For this to work, it should look like this:
app.get('/countries', accessControl, (req, res) => {
res.json(['US']);
});
or like this:
app.use(accessControl)
app.get('/countries', (req, res) => {
res.json(['US']);
});