Node: VM12:1 POST http://localhost:3000/auth net::ERR_CONNECTION_REFUSED - node.js

I am new to fullstack development and I want to deploy a project that will be used on the same network by different users. I have used angular for the front-end and node/express and MySQL for the backend. Before proper deployment, for testing purposes, I am accessing my application from another computer that is on the same network. The application, however, is throwing an error when I try to login.
VM12:1 POST http://localhost:3000/auth net::ERR_CONNECTION_REFUSED
Here's my backend code:
server.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const mysqlConnection = require('./connection');
const routes = require('./routes');
const http = require('http');
const path = require('path');
var app = express();
app.disable('x-powered-by');
app.use(express.static(__dirname + '/dist'));
app.get('/*', (req, res) => res.sendFile(path.join(__dirname)));
app.use(cors());
app.use(bodyParser.json());
app.use(routes);
const port = process.env.PORT || 3000;
const server = http.createServer(app);
server.listen(port, '0.0.0.0', () => console.log(`Running on port ${port}`));
routes.js
router.post("/auth", (req, res) => {
var email = req.body.email;
var password = req.body.password;
var accessBasic = "Basic";
var accessPremium = "Premium";
mysqlConnection.query("SELECT * FROM authorization WHERE email = ? AND password = ?", [email,
password], (err, results) => {
if(!err)
{
var myJSON = JSON.stringify(results);
var check_email = myJSON.search(/email/i);
var check_password = myJSON.search(password);
var check_access = myJSON.search(accessBasic);
var check_access2 = myJSON.search(accessPremium);
if ((check_email != -1) && (check_password != -1) && (check_access != -1))
{
res.send("Successfully Authorized to Basic Access");
}
else if ((check_email != -1) && (check_password != -1) && (check_access2 != -1))
{
res.send("Successfully Authorized to Premium Access");
}
else
{
res.send("Authorization failed");
}
}
else
{
console.log("Connection to authorization failed: " + err.message);
}
})
})
I have allowed incoming connections in my firewall and done everything but, couldn't find the reason why my endpoint is refusing to connect while trying to connect on device other than my system on the same network. I don't know what's wrong. Anybody has any idea what am I doing wrong? I have hosted my application on my system and accessing it from another on the same network.
EDIT: Since, this question has gained quite a lot of views, I would like to mention that I didn't change any of the firewall settings as mentioned above. All the default firewall settings of the Windows OS were used. I just deployed the app and ran it.
ANSWER: I was having an issue on the front-end. I was targeting localhost instead of the IP address of the system that the app was hosted on. See my answer below for the details.

For anyone who is going to see this in future. I was having an error on my front-end. Instead of calling http://localhost:3000/name-of-my-api-endpoint, I changed the localhost to the IP address of my system and then ran ng build --prod again in order to make new static files and serve them from node.js.

I have experienced the same issue with MongoDB
I have found out that the problem was my MongoDB wasn't connected to my localhost and the issue was related to tokens and authentication.
So I went to my terminal on my backend folder and ran the command -
npm install dotenv --save
Then I created my .env file located in my backend folder
and added the following commands
PORT=3000 APP_SECRET="RANDOM_TOKEN_SECRET"
MONGODB="mongodb+srv://youruser:yourpassword#cluster0.k06bdwd.mongodb.net/?retryWrites=true&w=majority"
Then called it in my app.js file
const dotenv = require("dotenv");
dotenv.config();
mongoose.connect(process.env.MONGODB,
{ useNewUrlParser: true,
useUnifiedTopology: true })
.then(() => console.log('Connected to MongoDB!'))
.catch(() => console.log('Failed to connect to MongoDB !'));
module.exports = app;
Finally I have added it in my backend/controllers/user.js
const token = jwt.sign(
{userId: user._id},
process.env.APP_SECRET,
{expiresIn: '24h'});
res.status(200).json({
userId: user._id,
token: token
});

You can access your app in the same network from your #IP not from localhost (127.0.0.1) change it to 192.168.1.X (your local #IP address) and make sure to changed it in your .env file.

Related

Receiving "Connection Refused" on NodeJS app for external connections on Windows 10

I'm receiving a "Connection Refused" error when attempting to connect to my NodeJS server running a REST API. My environment is Windows 10.
I've tried numerous only solution, but to no avail.
curl & postman works with localhost, but not external
nstat shows listening on 0.0.0.0:8143
Just testing the get at the moment, not post
Opened port on windows firewall
NGrok works (although I've read production use is not recommended)
using the following for external: http://xxx:8143/run/
let express = require('express');
let app = express();
var cors = require('cors')
let bodyParser = require('body-parser');
const logger = require('morgan')
let router = require('./routes/run.route');
// connection configure ---
const dbURI = 'mongodb://localhost:27017';
const dbName = 'rundata';
const Mongoose = require("mongoose");
Mongoose.connect(`${dbURI}/${dbName}`);
// app configure
app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({"extended" : false }));
app.use("/", router);
app.use(logger('dev', {skip: function(req, res) { return true; }}));
app.listen('8143','0.0.0.0',()=>{
console.log("server is listening on 8143 port");
})
const express = require('express');
const router = express.Router();
const Run = require("../schemas/run.model");
router.route("/run")
.get(function(req, res) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
.post(function(req, res) {
let data = req.body;
data.ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress || null;
let query = {'runId': req.body.runId}
Run.findOneAndUpdate(query, data, {upsert: true}, function(err) {
res.json(err ?
{"error" : true, "message" : err.message} :
{"error" : false, "message" : "Data added"}
);
});
});
module.exports = router;
Solution as follows:
Set port forwarding to my IP address (192.168.0.198:8143) on the router.
Set static lease for the IP to my machine, to ensure the port forwarding continues to work.
Now my my external IP (xxx:8143) points forwards directly to my machines IP.
I would guess there is another solution that doesn't involve configuring my router, but I haven't found it.

How can I connect my local node.js app to my Heroku Postgres database?

I've managed to get my Node.js app working properly with my Heroku Postgres database when the node application is deployed to Heroku. However having to deploy to heroku each time I make a code change is a bit arduous and I'd rather be able to develop locally and connect to the database from my local app.
https://devcenter.heroku.com/articles/connecting-to-heroku-postgres-databases-from-outside-of-heroku
The above article doesn't really describe how this is done, I'm not exactly sure what I need to do.
If I attempt to run my app locally and access an endpoint that queries my database I get
Error Error: connect ECONNREFUSED 127.0.0.1:5432
Whereas if I access the same endpoint from my heroku deployed app it works correctly.
Here's my app
const express = require('express')
const path = require('path')
const PORT = process.env.PORT || 5000;
const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
});
express()
.use(express.static(path.join(__dirname, 'public')))
.set('views', path.join(__dirname, 'views'))
.set('view engine', 'ejs')
.get('/', (req, res) => res.render('pages/index'))
.get('/users', async (req, res) => {
try {
const client = await pool.connect();
const result = await client.query('SELECT * FROM users');
const results = { 'results': (result) ? result.rows : null};
console.log(results);
res.status(200).json(results);
} catch (err) {
console.error(err);
res.send("Error " + err);
}
})
.listen(PORT, () => console.log(`Listening on ${ PORT }`));
I think you need to update the the process.env.DATABASE_URL on your local machine. From the error, it looks like the DATABASE_URL refers to localhost while you want to use the db hosted on Heroku.
I understand that you only want to use the remote db only. The error says you're unable to connect to 127.0.0.1:5432. This is the IP address of localhost, not the remote database. Your code is trying to connect to 127.0.0.1:5432 for some reason while it should be trying to connect to the remote db.
Did you use the dotenv to access process.env.DATABASE_URL ?
You need dotenv.config(); worked for me.

How to load mongodb URI from .env file on heroku?

I am a beginner to MERN stack and I deployed my nodejs app to heroku but the app is unable to connect to mongodb atlas and data from the database does not load when I give the mongodb uri via an environment variable.It works fine when I directly give the uri via a variable.Also when run locally,the app connects to atlas without any problem using environment variable.Any idea why its not working on heroku and how to fix it?
server.js
const express = require('express'); //nodejs framework for creating web apps
const cors = require('cors');
const mongoose = require('mongoose');
const path = require('path');
require('dotenv').config(); //for setting environment variables on server
const app = express(); //creating the app
//Serve static assets if in production
if(process.env.NODE_ENV ==='production'){
//Set static folder
app.use(express.static('client/build'));
app.get('*',(req, res) => {
res.sendFile(path.resolve(__dirname,'client','build','index.html'));
});
}
////////////////////////////////////////
const port = process.env.PORT || 5000;
app.use(cors()); //for cross origin resource sharing ie.cross domain requests
app.use(express.json()); //for handling json data
const uri = process.env.ATLAS_URI;
//its works fine when I give it as below
//const uri="mongodb+srv://jose:<password>#exercisecluster-rmqkg.gcp.mongodb.net/test?retryWrites=true&w=majority"
mongoose.connect(uri,{ useNewUrlParser: true, useCreateIndex: true ,useUnifiedTopology: true });
const connection = mongoose.connection;
connection.once('open',() => {
console.log('Database connection established successfully');
})
const exercisesRouter = require('./routes/exercises');
const usersRouter = require('./routes/users');
//executes the files in the second argument when user enters the url 'rooturl/firstargument'
app.use('/exercises',exercisesRouter);
app.use('/users',usersRouter);
app.listen(port,() => {
console.log(`Server is running on port:${port}`);
});
In your heroku project you need to setup an env variable ATLAS_URI and enter the value for your mongodb uri.
To do so go to the settings tab in your heroku app, then click on reveal config vars, and then enter the key and value for your mongo uri.
Hope this helps

Cant connect to node.js server through flutter app when requesting access to server from an android device on the same network?

I am trying to connect to a node.js server running on my laptop, i wrote a flutter application which connects to the server just fine when running through an emulator on the same laptop, but when i build an apk and install the app on my android device, its not connecting to the server. The laptop is connected to the mobile's hotspot. Also when i send the same request through the app 'REST Api Client', it connects to the server and gets the response just fine. What am i missing here or what can i try to make this work?
Future<String> _makeGetRequest(name, pass) async {
Response response1 =
await post(_localhost(), headers: {"username": name, "password": pass});
print(response1.body);
return response1.body;
}
String _localhost() {
if (Platform.isAndroid)
return 'http://192.168.43.236:3000/';
else
return 'http://localhost:3000';
}
Node.js server code
import express = require('express');
import bodyParser = require('body-parser');
const app = express();
const hostname: string = '192.168.43.236';
const port = 3000;
const username = 'username';
const pass = '123456';
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/', (req, res) => {
const postBody = req.headers;
console.log(postBody.username);
console.log(postBody.password);
if (req.headers.username == username && req.headers.password == pass)
res.status(200).send('Success');
else if (req.headers.username != username) {
res.status(404).send('User not found');
}
else if (req.headers.username == username && req.headers.password != pass)
res.status(401).send('Incorrect password');
else
res.status(500).send('Internal Server Error');
});
app.listen(port,hostname, () => {
console.info(`Server running at http://${hostname}:${port}/`);
});
Ok, so for anybody having the same issue, i got it working by providing internet permissions to my app. To do so just edit the AndroidManifest.xml file like so.

Nodejs RestAPI working on localhost but not on server

I developed a Node.js RestAPI to communicate with a MongoDB database. While I was developing using localhost everything worked fine, but now I need to deploy it to a server so users can test it.
The server is running Ubuntu 16.04, and I have successfully installed the software I need (Node.js and MongoDB) and I'm able to start the server, however, I can't make any request using the client.
If I ping the server I'm able to get a response. I have my Node.js RestAPI running on port 4000.
Any idea what I might be doing wrong or what I might have forgotten? This is the first time I'm deploying to a server.
My server.js file is:
const port = 4000
const bodyParser = require('body-parser')
const express = require('express')
const jwt = require('jsonwebtoken')
const cors = require("cors")
const mongoose = require('mongoose')
const databaseConfig = require('./database')
const server = express()
server.use(cors())
server.options('*', cors());
server.use(bodyParser.urlencoded({ extended: true }))
server.use(bodyParser.json())
server.set('superSecret', databaseConfig.secret)
server.listen(process.env.port || port, function () {
console.log('Listening')
})
mongoose.connect(databaseConfig.database, function(err, db) {
if (err) {
console.log('Unable to connect to the server. Please start the server. Error:', err);
} else {
console.log('Connected to Server successfully!');
}
});
module.exports = server
Any help is appreciated. Thank you.
To stop anyone from wasting time on this topic turns out the employee at my university that was supposed to make the host machine IP public forgot to do it! That was the problem, nothing else.

Resources