webpack devServer proxy doesn't catch my request - node.js

I have a UI app on http://localhost:8050/ and api server on http://foo.local.bar.com.
I logged in to the server directly, but I need the UI to send to cookie to the server too when I fetch GET method http://foo.local.bar.com/myapi/api/goo/maa .
In my config json I added devServer with proxy but it doesn't seem to work :
devServer: {
proxy: {
'/api/*': {
"target": "http://foo.local.bar.com",
logLevel: 'debug',
secure: false,
changeOrigin: true,
withCredentials: true,
cookieDomainRewrite: "localhost",
onProxyReq: proxyReq => {
console.log("onProxyReq 1 !!!!!!!!") // I don't see any console logs, so I also think the proxy doesn't "catch" my request...
proxyReq.setHeader("Cookie", ".MYCOOKIE=123445");
console.log("onProxyReq 2 !!!!!!!!", proxyReq)
}
}
}
},
But I still get "Authorization has been denied for this request." 401 error.
Any ideas? I tried, like, everything...

This is what helped me eventually:
proxy: {
'/myapi/api/*': { // changed the url
target: 'http://foo.local.bar.com/',
headers: {
Cookie: "MYCOOKIE=123445" // moved cookie to here
},
logLevel: 'debug',
secure: false,
changeOrigin: true,
withCredentials: true,
}
},

Related

how to fix "WebSocket connection to 'wss://apiURL/socket.io/?EIO=4&transport=websocket' failed: "

socket.io works fine on the localhost server, but after deploying it over https, I keep getting this error.
Client code:
export const socket = io.connect(process.env.REACT_APP_SERVER_URL, {
transports: ["websocket"],
// withCredentials: true,
cors: {
origin: [process.env.REACT_APP_SERVER_URL],
// origin: "*",
credentials: true,
},
});
Backend code:
const io = socketIO(server, {
cors: {
origin: [process.env.CLIENT_URL],
// origin: "*",
credentials: true,
},
});
When I type in the console.log "process.env.REACT_APP_SERVER_URL", the server API deployed by https comes in well, but I don't know what's wrong with socket communication.
As mentioned in the socket.io document, I tried using [credentials: true, withCredentials: true], and tried the same method as [origin: "*"] from Google, but all the same errors are coming out.
How can I solve it..?
Any help would be appreciated!

I can't setup proxy in mern stack(react-vite) and do not know the reason

I'm developing mern stack web application with react from vite.js and have a problem to deal with proxy.
my client side runs at http://localhost:3000 and server side runs at http://localhost:5000.
usually I use http-proxy-midlleware to connect my server and client like below
src/setupProxy.jsx
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app){
app.use(
createProxyMiddleware('/api', {
target: 'http://localhost:5000',
changeOrigin: true
})
)
};
However, It didn't work and still sent to localhost:3000 when I post data to server with axios. I googled it and figured out that with vite.js I need to use vite.config.js
so I set up vite.config.js like below
import { defineConfig, HttpProxy } from 'vite'
import react from '#vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
host: true,
port : 3000,
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true
}
}
},
})
and tried axios call again.
const result = await axios.post('api/users/login', dataToSubmit)
.then(res => res.data);
return result;
However, contrary to my expectation, It still sent to 3000 and I do not have a clue about what is going wrong :/
xhr.js:210 POST http://localhost:3000/api/users/login 404 (Not Found)
could you tell me how to fix it? thanks for reading, your help will be appreciated.
It's required to specify secure: false like this. Reference
export default defineConfig({
plugins: [react()],
server: {
host: true,
port : 3000,
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true,
secure: false
}
}
},
})
I had this problem too.
My backend runs on http://localhost:8080, while my frontend runs on http://localhost:3000.
To resolve the cross-origin issue, I used the proxy alternative, but every request was returning a 404 error.
My solution was to add the rewrite: (path) => path.replace(/^\/api/, "") function in the vite settings file.
Finally, the final result of the file was:
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
server: {
proxy: {
"/api": {
target: "http://127.0.0.1:8080",
changeOrigin: true,
secure: false,
ws: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
port: 3000,
},
plugins: [react()],
});
Your port in vite.config.js file is set to 3000. So you have to set your target in src/setupProxy.jsx to 'http://localhost:3000'.
hope it helps

Multiples devServer proxies and multiples ports

I need to query automated routes generated from from https://github.com/o1lab/xmysql on port 3000 from my vue.js dev env running on port 8080 .
vue.config.js :
module.exports = {
devServer: {
proxy: {
"/api": {
target: "http://localhost:80", // Works perfeclty
},
"/": {
target: "http://localhost:80", // Works perfectly
},
"/generated": { // Not working
target: {
port: 3000
},
secure: false,
ws: false,
changeOrigin: true
}
},
hot: true,
liveReload: true,
}
};
xmysql params :
xmysql -h localhost -u root -p password -n 3000 -a /generated/ -d myDatabase
My vue.js axios "get" query :
axios
.get('/generated/meetings', {
headers: {
'Access-Control-Allow-Origin': 'all',
}
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error);
});
The Error :
Cannot GET /generated/meetings
I can access localhost routes on my localhost:3000 into my firefox navigator and they work really well:
Looks like the proxy is not working, any idea ?
I have tried this other vue.config.js params with no luck :
devServer: {
proxy: {
"/api": {
target: "http://localhost:80",
// ,pathRewrite: {'^/api' : ''}
},
"/": {
target: "http://localhost:80",
},
"/generated": {
target: "http://localhost:3000",
pathRewrite: { '/generated': '' },
secure: false,
ws: false,
changeOrigin: true
}
},
hot: true,
liveReload: true,
}
The only thing working is this query :
axios
.get('localhost:3000/generated/meetings', {
headers: {
'Access-Control-Allow-Origin': 'all',
}
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error);
});
But then, there is a CORS problem, and I can't get 'response', even if it gets displayed in the firefox console query, I can only get the error .
sorry, It seems that it was a /api/ conflict caused by a generic mongoDb back end starting by /api/ running in parrallel.
I ended up with this vue.config.js . Now my Mysql queries will go to /api routes, and my mongoDb queries will go to the generic-api routes, so I am able to handle 2 databases in one vue.js app:
module.exports = {
devServer: {
proxy: {
"/api": {
target: "http://localhost:3000", // This is set for xmysql routes generator https://github.com/o1lab/xmysql
},
"/": {
target: "http://localhost:80", // Serving the vue.js app
},
"/generic-api": {
target: "http://localhost:80", // When using generic-crud.js with mongoDb
}
},
hot: true,
liveReload: true,
}
}
And this is my xmysql standard config , now :
xmysql -h localhost -u root -p password -n 3000 -d myDatabase
EDIT : NEW :
Ho no, when I trigger NPM RUN BUILD, my /api routes are not working any more in my vue.js production app!
RESOLVED : Added a NODE EXPRESS proxy like this in my server.js node file :
// -------------------------------
// PROXY ALL API ROUTES QUERIES TO PORT 3000 TO USE WITH MYSQL ROUTES GENERATOR https://stackoverflow.com/questions/10435407/proxy-with-express-js
// -------------------------------
var proxy = require('express-proxy-server');
app.use('/api', proxy('http://localhost:3000/api'));
Now, even my vue.js production app queries are proxied to http://localhost:3000 , so it should work on heroku ...

Lusca csrf not working as expected - http request using old token

I was trying to set up CSRF protection with lusca on my Express.js application. Not it looks like this:
this.app.use(lusca({
csrf: {
cookie: {name: '_csrf'}
},
hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
nosniff: true,
referrerPolicy: "same-origin",
xframe: "SAMEORIGIN",
xssProtection: true,
}));
And on client side as follow:
const res = await axios.post(`${Constants.apiUrl()}/${Constants.paths.login}`,
credentials, {
withCredentials: true,
xsrfCookieName: '_csrf'
});
On the server-side, I also set some headers to be able to send cookies with request - res.header('Access-Control-Allow-Credentials', 'true').
Probably I'm missing some important part of how CSRF protection works. Now each time with the response, I'm getting new csrf token but this means that my new HTTP POST request sending the previous token that already outdated.
What I'm missing?
Finally, I found the problem after testing for 3 hours. You need to add the secret of the csrf. Also, if you are using Angular, you need to add angular: true into the csrf.
this.app.use(lusca({
csrf: {
cookie: {name: '_csrf'},
secret: 'qwerty'
},
hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
nosniff: true,
referrerPolicy: "same-origin",
xframe: "SAMEORIGIN",
xssProtection: true,
}));

Axios isn't sending session data

I've developed an app using React, Mongodb, Node, and Express and i'm using sessions for authentication. On the backend, I can successfully set a cookie a store a userID however when I try to make requests from the react app using axios, the userID session data is not sent.
This is my session config on the backend:
app.use(session({
name: SESS_NAME || "***",
secret: SESS_SECRET || "***",
saveUninitialized: false,
resave: false,
store: new MongoStore({
mongooseConnection: db,
collection: 'session',
ttl: parseInt(SESS_LIFETIME) / 1000 || (60 * 60 * 48) / 1000
}),
cookie: {
sameSite: true,
path: '/',
domain: APP_DOMAIN || 'localhost:4000',
secure: false, //NODE_ENV === 'production',
maxAge: parseInt(SESS_LIFETIME) || 60 * 60 * 48
}
}));
My cors is configured as follows:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:4000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", true);
next();
});
const corsConfig = {
origin:['http://localhost:3000', 'http://localhost:4000' ],
methods:['GET','POST'],
credentials: true,
};
app.use(cors(corsConfig));
after logging in I set the userID in my user Routes, which I confirmed is set by console logging:
req.session.userId = user._id;
This is an example request from my react app
axios.get('/user/auth', { withCredentials: true })
.then(response => {
...
Note that my app is being served on the same domain - I'm using the node app to serve the react app. my folder structure is similar to the following
- APP PARENT FOLDER
-CLIENT //Whole react app
-MODELS
-ROUTES
-SERVER.JS
-PACKAGE.JSON
-NODE_MODULES
I have searched everywhere and tried everything I can think of... no luck. I would appreciate any help!
I've already checked articles on stack overflow and tried to implement the fixes but have had no luck. I've tried the following fixes:
// in my index.js file
axios.defaults.withCredentials = true;
and adding
{ withCredentials: true }
to all of my requests
When I take the userid created at login (ex: 5d6b5d2b09f7d1332543ba90) and manually plug this into the user Route on the backend then everything works fine.
When I console log the session on every request made by the react app it looks like this:
Session {
cookie:
{ path: '/',
_expires: 2019-09-05T05:38:09.657Z,
originalMaxAge: 172800,
httpOnly: true,
sameSite: true,
domain: 'localhost:4000',
secure: false },
}
When it should look like this:
Session {
cookie:
{ path: '/',
_expires: 2019-09-05T05:38:09.657Z,
originalMaxAge: 172800,
httpOnly: true,
sameSite: true,
domain: 'localhost:4000',
secure: false },
userId: 5d6b5c2b03f7d5532543ba90 }

Resources