Node, Express, and Mongoose: Authentication failed error - node.js

I'm new to Node/Express/Mongo/MLab and backend programming in general. I am trying to submit a post request to an MLab database and running into trouble. I think my problem is with Mongoose and MLab.
Here is my Glitch project
I'm getting error MongoDB connection error: { MongoError: Authentication failed. Why am I getting this error? Is there a problem with my mongoose.connect function and credentials? Is MLab not properly set up?
'use strict';
var express = require('express');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var validUrl = require('valid-url');
var dns = require("dns");
var cors = require('cors');
var app = express();
// Basic Configuration
var port = process.env.PORT || 3000;
// Hooks up app to MLab MongoDB database by using the .env variable I created
// Doesn't work. Data is not submitted to MLab and /api/shorturl/new endpoint freezes up when form is submitted
mongoose.connect(process.env.MONGODB_URI, {useMongoClient: true});
/*
Also doesn't work
mongoose.connect(process.env.MONGODB_URI, {
"auth":{"authSource": "admin"},
"user": "admin",
"pass": "password"
});
*/
// Should allow us to use promises with mongoose
mongoose.Promise = global.Promise;
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// Sets up a Schema for the DB
var urlSchema = new mongoose.Schema({
url: String,
shortenedUrl: String
});
// Sets up a model for the DB
var Url = mongoose.model("Url", urlSchema);
app.use(cors());
/** this project needs to parse POST bodies **/
// you should mount the body-parser here
var urlencodedParser = bodyParser.urlencoded({ extended: false });
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.use('/public', express.static(process.cwd() + '/public'));
// parse application/x-www-form-urlencoded
app.get('/', function(req, res){
res.sendFile(process.cwd() + '/views/index.html');
});
app.get("/api/shorturl/new", function (req, res) {
res.sendFile(process.cwd() + '/views/form.html');
//res.send({hi: "hi"});
});
app.post("/api/shorturl/new", urlencodedParser, function (req,res) {
// Gets URL from form
//var url = req.body.url;
//console.log(url);
var myData = new Url(req.body);
console.log("myData : " + myData);
myData.save()
.then(item => {
res.send("Successfully saved to DB");
})
.catch(err => {
res.status(400).send("Unable to save to DB");
});
});
app.listen(port, function () {
console.log('Node.js listening ...');
});

As other people have commented the code itself looks like it should work.
so the immediate suspect is the URI,
obviously you are not going to post the full string for all of us to see, but one theory that comes to mind is your password having characters that need encoding,
try using javascripts encodeURIComponent on the password.

Related

Hi, I am using Express with MongoDb, Whenever I make a post request, it shows that message (model made using mongoose) is not a constructor

Whenever I make a post request, it shows that message is not a constructor. Here message is a model that I made using mongoose.
And I am exporting this model through
module.exports = message and using this exported model in form_post.js file
my app.js file
const express = require('express');
const app = express();
const path = require("path");
const mongoose = require('mongoose');
const port = 3000;
const form_display = require('./routes/form_display');
const form_post = require('./routes/form_post');
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
//Backend Connection
mongoose.connect("mongodb://127.0.0.1:27017/sudeepkart", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
var db = mongoose.connection;
db.once("open", function () {
console.log("We are Connected !!");
});
// Pug Specific
app.set('view engine', 'pug') //Setting View Engine as Pug
app.set('views', path.join(__dirname, 'views')) //Setting views directory so that pug files can be fetched from he views directory
// Express Specific
app.use(form_display);
app.use(form_post);
app.use('/static',express.static('static'))
app.use((req, res, next)=>{res.status(404).send('<h2>Error Page Not found</h2>')});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
})
my form_post.js file
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Message = require('../models/message.model')
const port = 3000;
router.use(express.urlencoded({ extended: false }))
router.use(express.json())
router.post('/message', function (req, res) {
// Creating New Object
var newMsg = new Message(req.body);
newMsg.save(function (err, msg) {
});
res.send('Your message has been successfully submitted');
})
module.exports = router;
my models/message.model.js file
const mongoose = require('mongoose');
// New Schema and New Model
var message_schema = new mongoose.Schema({ "id":String, "message":String });
var message = new mongoose.model("message_model", message_schema); // in other words model is a synonym for collection
module.exports = message;
Try destructuring it:
const {message} = require('../models/message.models')
MDN Documentation for destructuring
To answer your comment question, because you're trying to import Message while only exporting message. On your module.exports, I would reccomend always doing module.exports = {variable1, function2} etc, so you can destructure it and you can easily debug any issues (and stop confusion with variables too!)

Why localhost not loading even after node server and mongodb loaded?

I've started learning on MEAN development. I had setup my express server and also my mongodb connection. On running node server in terminal the server starts running and also the mongo was able to connect but the localhost:8081/api/videos is not loading. I cleared cache and cookies but still no solution. I am attaching the code below.
server.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const api = require('./server/routes/api');
// Port for express server
const port = 8081;
const app = express();
app.use(express.static(path.join(__dirname,'dist/mean')));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json);
app.use('/api', api);
app.get('*', (req,res)=> {
res.sendFile(path.join(__dirname, 'dist/mean/index.html'));
});
app.listen(port, function(){
console.log('Server running at localhost:' + port);
});
api.js
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Video = require('../models/video');
// Creating mongo db connection
const db = 'mongodb+srv://<username>:<password>#training-qfjgb.mongodb.net/test?retryWrites=true&w=majority';
mongoose.Promise = global.Promise;
mongoose.connect(db, { useUnifiedTopology: true, useNewUrlParser: true }, err => {
if(err) {
console.log('Error: '+err);
}
else {
console.log('Successfully connected to mongodb');
}
});
router.get('/videos', function(req, res){
console.log('Get request for all videos');
Video.find({}).exec(function(err, videos){
if(err)
{console.log('Error retrieving videos');}
else
{res.json(videos);}
});
});
module.exports = router;
video.js (This is for the schema)
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Creating database schema
const videoSchema = new Schema({
title: String,
url: String,
description: String
});
// Creating model of database videoplayer as model and then exporting
module.exports = mongoose.model('video', videoSchema, 'videoplayer');
const db = 'mongodb+srv://username:password#training-qfjgb.mongodb.net/test?retryWrites=true&w=majority';
username:password should be changed.
admin:12345(as you using)
const db = 'mongodb+srv://username:password#training-qfjgb.mongodb.net/test?retryWrites=true&w=majority';
Check this part thoroughly , Whether the collection name, format of the text are given correctly

node, express, mongoose don't work together

Hej people
I try to create some fullstack app (base on one tutorial) and I have some problem with understand how backed part work. Teoreticlly, then I did this tutorial first time, everything was working. But now, then I try to something new base on it, I see how many things I don't understand. Basically, why it won't work.
I generate express app. My app.js looks that:
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mongoose = require('mongoose');
var cors = require('cors');
mongoose.connect('mongodb://localhost/covid', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
}).then(() => console.log('connection successful'))
.catch((err) => console.error(err));
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var casesRouter = require('./routes/cases');
var app = express();
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api', casesRouter);
module.exports = app;
routers/cases.js:
var express = require('express');
var router = express.Router();
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var Cases = require('../models/Cases.js');
server.listen(4000)
// socket io
io.on('connection', function (socket) {
socket.on('newdata', function (data) {
io.emit('new-data', { data: data });
});
socket.on('updatedata', function (data) {
io.emit('update-data', { data: data });
});
});
// list data
router.get('/', function(req, res) {
Cases.find(function (err, cases) {
if (err) return next(err);
res.json(cases);
});
})
module.exports = router;
and schema:
var mongoose = require('mongoose');
var CasesSchema = new mongoose.Schema({
id: String,
name: String,
location: String,
state: String,
});
module.exports = mongoose.model('Cases', CasesSchema);
ok, it's all.
So now I run it from my console by nodemon. In console everything looks ok. No error, and message that everything is ok. But app is not working:
1) I expect that this part:
mongoose.connect('mongodb://localhost/covid', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
}).then(() => console.log('connection successful'))
.catch((err) => console.error(err));
should created me now new schema "covid" with object Cases with keys id, name, location, state. It didn't happen. I installed Compass to easiest examination my mongodb and I can see, that I don't have something like covid. ok, I created it manually, But, as I understand, it should be done automaticlly after I run nodemon.
2) I expect that I can examination my backend via postman. https://localhost:3000/api/ (3000 - nodemon default port), but I
Could not get any response There was an error connecting to
https://localhost:3000/api/.
and it's everything. I can't see this error neither in console nor postman.
Maybe I don't understand something with ports in express app, or I don't understand something with mongoDB. But google didn't help me. It did only bigger mess in my head. So maybe someone of you can explain me how it should work and why?

Get data from mongoDB using node.js, connection works but no data is showing

So i have made an application using node.js and connected it to mongoDB, but no data is showing, it is simply showing and empty json data file []. The database name is sample_geospatial and the collection is named shipwrecks and all ip addresses are OK to connect with.
Why am i not succeeding with my task to show the data in the browser?
This is my app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var shipwrecksRouter = require('./routes/shipwrecks');
var app = express();
// Database connect with moongoose
var mongoose = require('mongoose');
mongoose.connect('mongodb+srv://gockzor:***********#cluster0-boypg.azure.mongodb.net/test?retryWrites=true&w=majority');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
console.log("Kopplingen lyckades!");
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/shipwrecks', shipwrecksRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
module.exports = app;
This is my model
var mongoose = require('mongoose');
var WrecksSched = new mongoose.Schema({
recrd: String,
vesslterms: String,
feature_type: String,
chart: String,
latdec: Number,
londec: Number,
gp_quality: String,
depth: String,
sounding_type: String,
history: String,
quasou: String,
watlev: String,
coordinates: Array,
}, {
collection: 'shipwrecks'
});
module.exports = mongoose.model('ShipwrecksModel', WrecksSched);
This is my routes file
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var ShipwrecksModel = require('../models/ShipwrecksModel.js');
router.get('/', function (req, res, next) {
ShipwrecksModel.find(function (err, wrecks) {
if (err) return next(err);
else {
res.json(wrecks);
}
});
});
module.exports = router;
Putting it as an answer :
If you're seeing [] in the api response rather than an error -
then the issue could either be you're not able to connect to proper
collection name(if you're sure collection has data in it) or correct db where your collection exists.
So from your DB url :
'mongodb+srv://gockzor:***********#cluster0-boypg.azure.mongodb.net/test?retryWrites=true&w=majority'
You've got connected to test DB, So is that your DB where your collection shipwrecks exists ? If not the try to switch to actual DB after getting connected or replace test in url with actual DB name.
So by default you'll get an url w.r.t. to test db when you get it from Atlas mongoDB. So replace it on url once in all or you can switch it over the code after connecting to DB, using useDb function. Ex. :-
From code a basic way to switch DB ::
async function myDbConnection() {
const url = mongodb+srv://gockzor:***********#cluster0-boypg.azure.mongodb.net/test?retryWrites=true&w=majority';
try {
await mongoose.connect(url, { useNewUrlParser: true });
console.log('Connected Successfully')
mongoose.connection.useDb('myDB'); // Switching happens here..
/**
* Do some DB transaction with mongoose models as by now models has already been registered to created DB connection
*/
} catch (error) {
console.log('Error connecting to DB ::', error);
}
}
Or you can have something like this directly in url ::
const dbUrl = mongodb+srv://gockzor:***********#cluster0-boypg.azure.mongodb.net/myDB?retryWrites=true&w=majority'

error in mongodb mongoose used in nodejs express app:does not write to DB when using module.exports

I have successfully generated and launched a nodejs application with express generator.This part is OK.
I have also created a standalone (single .js file) prototype of mongoDB setup (using mongoose - first time for me). OK
They do the job well but I am stuck when I combine the 2.
I assume my mistake is in the statements of module.exports but I can't figure out how to fix it.
Can anybody please help me to rewrite it?
nb I use "mongoose": "~5.3.16", (...if version is important ?)
My code (I skip some long parts):
/bin/www (for info, probably not the problem):
var app = require('../app');
var debug = require('debug')('api-dfv2:server');
var http = require('http');
const loadConfig = require('../public/javascripts/loadConfig.js');
const config = loadConfig.getConfig();
var port = normalizePort(config.port);
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
function normalizePort(val) {(I skip...)
}
function onError(error) {(I skip here some code to handle errors+event listener for http server "listening" event...)
app.js :
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var loadConfig = require('./public/javascripts/loadConfig.js');
var Conversation = require('./src/conversation');//declared but never read probably something wrong there
//the routers we need
var indexRouter = require('./routes/index');
var dfv2Router = require('./routes/dfv2');
//initiate express with moment
var app = express();
//link with moment module
app.locals.moment = require('moment');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
//app.set('view engine', 'jade');>>upgrade to pug
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//let's load the initial config (or defaults)
//it will exit if no credentials are provided.
loadConfig.setConfig();
/**
* map the routes
*/
app.use('/', indexRouter);
app.use('/dfv2', dfv2Router);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
in dfv2.js, I receive POST requests from a chat system and I want to store that content in mongoDB :
var express = require('express');
var router = express.Router();
const conversation = require('../src/conversation')
/* POST received from chat system */
router.post('/', function(req, res, next) {
dialogflowv2.getDFResponse(req.body)//I generate the answer to the chat
.then((DFanswer) => {
console.log(JSON.stringify(DFanswer));//not a nice way to debug but it works until that point
var currentConversation = new conversation;
console.log('test5');
currentConversation = {"moment": "test"};//I should write the full mapping with the body etc. here just to test one field
console.log(JSON.stringify(currentConversation));
currentConversation.save() // THIS IS WHERE IT GOES WRONG XXXXXX
//.then(function(tmp) {console.log("ok : ",tmp)})
//.catch(function() {console.log("DB error :")})
res.status(200).json(DFanswer);
})
.catch(err => res.status(400).json(JSON.stringify(err.message)))
})
module.exports = router;
for info, conversation.js
var mongoose = require('mongoose');
const server = '127.0.0.1:27017'; // DB SERVER
const database = 'test_laurent'; // DB NAME
mongoose.connect(`mongodb://${server}/${database}`,{useNewUrlParser: true})
.then(() => {
console.log('Database connection successful - system ready')
})
.catch(err => {
console.error('Database connection error')
})
//get mongoose to use the global promise library
mongoose.Promise = global.Promise;
var db = mongoose.connection;
//to bind error of DB with console
db.on('error',console.error.bind(console, 'MongoDB connection error:'));
let mySchema = new mongoose.Schema(
{
body: String,
sessionId: String,
moment: String
})
let conversation = db.model('conversation', mySchema);
module.exports = conversation;
The result is that my DB doesnt receive anything. But it work well if I take all the code of conversation.js as standalone app (POST > generate schema > construct object > object.save > my collection is then created and visible in Compass so the DB and its connection is not the problem).
thank you in advance, any hint is welcome.
conversion is a constructor but you are not calling that when creating a new conversation.
Do this:-
const currentConversation = new conversation({moment: test});
Also .save() returns a promise so you have to await it so append a .then.catch block to .save method
currentConversation.save()
.then()
.catch()

Resources