How to proxy a websocket properly? - javascript

I'm having trouble proxies websocket using http-proxy-middleware. The error I got was Websocket connection to https://api.dsm-staging.test.site failed.
Here's the code I'm using in express :
const { createProxyMiddleware } = require("http-proxy-middleware");
const options = {
target: "https://api.dsm-staging.test.site",
changeOrigin: true,
ws: true,
};
const proxy = createProxyMiddleware(options);
app.use("/v1/*", proxy);
This is my code in front end :
this.socket = io("https://api.dsm-staging.app.test.site", {
reconnectionAttempts: 5,
reconnectionDelayMax: 10000,
extraHeaders: {
Authorization: `Bearer ${token}`,
},
transports: ["websocket"],
});
this.socket.on("connect", () => {
console.log(this.socket.connected);
});

Related

Strapi session not found on Chrome

I built a website with Nuxt and Strapi. I added a cart system using the ctx.session. It works well on local, but when in prod, the session can't be retrived when using Chrome or Safari. But it's perdect with Firefox.
I logged to see what's happening and it seems that the sessions is never stored. After an action is done, nothing remains.
Here is my middleware.js :
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
//...
settings: {
cors: {
enabled: true,
// headers: '*',
credentials: true,
origin: isProd
? ['https://xxxxxx.com', 'https://yyyyy.xxxxxx.com']
: ['http://localhost:3000', 'http://localhost:1337']
},
logger: {
level: 'trace'
}
},
}
and my server.js :
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
admin: {
auth: {
secret: env('ADMIN_JWT_SECRET', 'XXXXXXXXXXXX'),
},
},
cron: { enabled: true }
});
On the front side, here is my Axios config :
const apiClient = axios.create({
baseURL: `${process.env.baseUrl}/`,
withCredentials: true,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
timeout: 10000,
})
Thank you
I finally found the solution!
I was missing the session activation in the middleware.js config file.
module.exports = {
//...
settings: {
...otherSettings,
session: { enabled: true }
},
}

How to fix CORS policy issue with get request?

please help me to solve CORS policy issue, it happens when I'm trying to make a get request to applications endpoint, and issue is only reproducible from http://localhost:8080/ on prod request works fine.
vue.config.js file
module.exports = {
devServer: {
proxy: 'https://spinstatus.zenoss.io/'
}
}
request method
const grabApps = async () => {
const res = await axios({
method: 'get',
url: `${spinnakerURL}/gate/applications`,
withCredentials: false,
crossdomain: true,
headers: {
'Access-Control-Allow-Origin': '*',
}
});
return res.data || []
}
error
headers from localhost request
headers from prod request
Change the devServer configuration in vue.config.js like this:
module.exports = {
devServer:
{
proxy:
{
'/gate':
{
target: 'https://spinstatus.zenoss.io',
changeOrigin: true,
onProxyReq: (proxyReq, req, res, options) =>
{
proxyReq.setHeader('Origin', 'https://spinstatus.zenoss.io');
}
}
}
}
};

missing authentification token for REST request elastic search

It's the first time I'm posting a question here: I'm creating a website in AngularJS for the front end and NodeJS for the back end. This website is supposed to give me information about my elastic search clusters, get some information from Elasticsearch index. I have tried to use Elasticsearch Javascript API to do my request but it doesn't work.
I'm using ElasticSearch 5.4
Here's an example of request :
var client = new elasticsearch.Client ({
host: 'https://noev02pe.fr:9200',
auth: 'user:password',
log: 'trace',
headers: {
'Authorization': 'Basic user:password',
}
});
export function connect() {
client.search({
index: 'metric-prod*',
q: 'kafka'
}
, function (error, response) {
console.log(response);
});
}
and the response on the console is :
{ error:
{ root_cause: [ [Object] ],
type: 'security_exception',
reason: 'missing authentication token for REST request [/metric-
prod*/_search?q=kafka]',
header: { 'WWW-Authenticate': 'Basic realm="security" charset="UTF-8"'
} },
status: 401 }
I also tried doing classic post request :
export function createUser(request,response,next){
var username = request.params.username;
var userData = querystring.stringify(request.body);
console.log(userData);
var options ={
hostname: 'noev02vr.fr',
port: 9200,
rejectUnauthorized: false,
path: "_xpack/security/user/"+username,
method:'POST',
headers: {
'Authorization': 'Basic ' + prodPass,
'Content-Type': 'application/json',
'Content-Length': userData.length
}
};
var post_req=http.request(options, function(res){
console.log('post user reussi');
res.on('data', function(data){
response.writeHead(res.statusCode);
response.write(data);
console.log(res.statusCode);
});
});
post_req.write(userData);
post_req.end();
}
and I get a 500 error.
Basic Authentication
const { Client } = require('#elastic/elasticsearch')
const client = new Client({
node: 'https://localhost:9200', //Replace with your URL.
auth: {
username: 'elastic',
password: '*****' //Replace with your password
}
})
Otherwise, you can provide your credentials in the node(s) URL
const { Client } = require('#elastic/elasticsearch')
const client = new Client({
node: 'https://username:password#localhost:9200'
})
If you have enable ssl then this are the config
const { Client } = require('#elastic/elasticsearch')
const client = new Client({
node: 'https://localhost:9200',
auth: {
username: 'elastic',
password: '*****'
},
ssl: {
ca: fs.readFileSync('./cacert.pem'),
rejectUnauthorized: false
}
})
You can get Your username and password refer this link
https://www.elastic.co/guide/en/cloud-enterprise/current/ece-password-reset-elastic.html

ReactJS get external Json

I want to make a component with Reactjs to get json from an url, I tried with (Axios, Fetch, Jsonp...) and other package.
With Axios and Jsonp I had CORS errors, impossible to fix the issue.
With Fetch I can disable the cors with 'mode': 'no-cors' but no data are collected.
Here is my code :
getData() {
const header = {
'Access-Control-Allow-Origin': '*',
'mode': 'no-cors'
};
this.serverRequest = fetch('https://www.cryptopia.co.nz/Exchange/GetTradePairChart?tradePairId=5355&dataRange=2&dataGroup=60', header)
.then(response => response.json())
.then(json => {
console.log(json);
this.setState({
altcoinsData: json
});
}).catch(e => {
console.log(e);
});
}
Error :
SyntaxError: Unexpected end of input
at App.js:30
at
If you are using webpack-dev-server, add proxy service in webpack.config.js to avoid CROS.
devServer: {
port: 8080,
stats: 'errors-only',
proxy: {
'/api': {
target: 'http://localhost:20404', //http://localhost:20403/',
secure: false
}
}
}
If not you can start a express server with http-proxy-middleware to proxy the ajax request to the required end point. Please find a sample server.js which includes express and webpack config.
Hope it helps :)
var webpack = require('webpack');
var Agent = require('agentkeepalive');
var config = require('./webpack.config.js');
var https = require('https');
var proxy = require('http-proxy-middleware');
const express = require('express');
const path = require("path");
const webpackDevMiddleware = require('webpack-dev-middleware');
var app = express();
var compiler = webpack(config);
app.use(
'/api',
proxy({
target: 'http://10.134.116.186:1521/',
changeOrigin: true,
agent: new Agent({
maxSockets: 100,
keepAlive: true,
maxFreeSockets: 10,
keepAliveMsecs: 100000,
timeout: 6000000,
keepAliveTimeout: 90000 // free socket keepalive for 90 seconds
})
})
);
app.use(
'/dist',
proxy({
target: 'http://localhost:8080/',
changeOrigin: true,
agent: new Agent({
maxSockets: 100,
keepAlive: true,
maxFreeSockets: 10,
keepAliveMsecs: 100000,
timeout: 6000000,
keepAliveTimeout: 90000 // free socket keepalive for 90 seconds
})
})
);
app.use(
webpackDevMiddleware(compiler, {
hot: true,
historyApiFallback: true,
contentBase: config.output.path,
publicPath: config.output.publicPath,
headers: { 'Access-Control-Allow-Origin': '*' }
})
);
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.listen(7071, 'localhost', function(err, result) {
if (err) {
return console.log(err);
}
console.log('Webpack Dev Server is fired up!!');
});

Setup Node.js HTTPS to work with HAPROXY

I'm trying to make my nodejs app to communicate with HAPROXY via https. The idea is that nodejs sends message to haproxy via https, haproxy routes message forward.
I used request.js library and all worked fine, but now I need to perform this task without any libraries. The scenario is following. If environment variable is 1, I should use HTTP, in other cases -HTTPS. The problem is that when I use https and haproxy, I get "Socket hangup error", but everything works fine with request.js. Here is my code.
const protocol = process.env.NODE_ENV === 1 ? require('http') : require('https');
then I configure HTTPS
this.api = url.parse(app.get('API_HAPROXY'));
this.options = {
port: this.api.port,
hostname: this.api.hostname,
path: '/api/report',
method: 'POST',
headers: {
"Content-Type": "application/json",
},
rejectUnauthorized: false,
requestCert: true,
agent: false
};
Because I don't want to use ca to validate ssh keys I use NODE_TLS_REJECT_UNAUTHORIZED=0
reportData(json) {
const req = protocol.request(this.options, (res) => {
res.on('error', (err) => {
this.logger.error(`Failed to report ${err.message}`)
})
});
req.write(JSON.stringify(json));
req.end();
req.on('error', (err) => {
this.logger.error(`Failed to report ${err.message}`);
});
}
In this case I get socket hangup error while using HTTPS
Here is my request configuration
request({
uri: `${this.api}/api/report`,
method: 'POST',
json,
}, (err, response) => {
if (err || response.statusCode !== 200) {
this.logger.error(`Failed to report : ${err ? err.message : response.statusCode}`);
} else {
this.logger.info(`Report was sent`);
}
});
The issue was fixed by adding content-length header to the options.headers.
this.api = url.parse(app.get('API_HAPROXY')); this.options = {
port: this.api.port,
hostname: this.api.hostname,
path: '/api/report',
method: 'POST',
headers: {
"Content-Type": "application/json",
"Content-Length: <calculated length of the object you want to send in bytes >
},
rejectUnauthorized: false,
requestCert: true,
agent: false
};

Categories