Login Form in Node.js & MongoDB (mongoose) - javascript

I'm almost beginner to web dev. I'm making a pretty basic web page for login authentication. All I'm trying to do is to check user credentials (username & password) on my LoginPage from the database (mongoose) and redirect to the next page (MainPage) if they are correct.
Login.ejs (.html) file
<html>
<head>
<title>Login</title>
</head>
<body>
<form id="form_Login" action="/MainPage" method="post">
<input id="txt_username" type="text" required>
<br><input id="txt_password" type="password" required>
<br><input type="submit" value="Login">
</form>
</body>
</html>
app.js file
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = new Schema ({
username : String,
password : String
});
mongoose.model('User',User);
mongoose.connect('mongodb://localhost:27017/MyDB');
app.set('view engine', 'ejs');
app.get('/',function(req, res) {
res.render('LoginPage');
});
app.get('/MainPage',function(req, res) {
res.render('MainPage');
});
app.post('/MainPage', function(req, res) {
// new code should come over here
res.redirect('/MainPage');
});
app.get('*', function(req, res) {
res.send('Bad Route!');
});
var server = app.listen(3000, function() {
console.log('listening on port 3000.');
});
Any help would be appreciated.

I would suggest you use the passport.js library for that.
Not only does it provide you with a good way to create local authentication, you can later on integrate google, facebook and twitter (or any oAuth) social authentication methods.
You can read the documentation which should provide you with a good starting point, or any one of these examples:
http://passportjs.org/docs
http://mherman.org/blog/2013/11/11/user-authentication-with-passport-dot-js/#.VYAS0PlViko
http://mherman.org/blog/2015/01/31/local-authentication-with-passport-and-express-4/#.VYAS0vlViko
https://scotch.io/tutorials/easy-node-authentication-setup-and-local ( I have used this one in the past)
I suggest you start by using the passport-local scheme, which will give you exactly what you need. https://github.com/jaredhanson/passport-local

Use the body-parser middleware to get your form data and use it to query your database. First you need to do a npm install body-parser. Then you could try something like the following. Note that this is very rough code however and you should probably use some other excellent libraries to handle authentication.
var express = require('express');
var app = express();
var bodyParser = require('body-parser);
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = new Schema ({
username : String,
password : String
});
mongoose.model('User',User);
mongoose.connect('mongodb://localhost:27017/MyDB');
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.get('/',function(req,res)
{
res.render('LoginPage');
});
app.get('/MainPage',function(req,res)
{
res.render('MainPage');
});
app.post('/MainPage', function(req, res)
{
// new code should come over here
User.findOne({username: req.body.username, password: req.body.password}, function(err, user){
if(err) {
console.log(err);
}
else if(user){
res.redirect('/MainPage');
}
else {
console.log('Invalid');
}
});
});
app.get('*', function(req,res)
{
res.send('Bad Route!');
});
var server = app.listen(3000, function() {
console.log('listening on port 3000.');
});

You can use bodyPasser to get input from the html. (npm i body-parser. https://www.npmjs.com/package/body-parser).
You can use the mongoose to save the user and find the user (npm i mongoose) https://www.npmjs.com/package/mongoose.
I used here ejs.
Using the findOne you can find the register user is available or not https://mongoosejs.com/docs/api/model.html#model_Model-findOne.
//jshint esversion:6
const express = require('express');
const bodyPasser = require('body-parser');
const ejs = require('ejs');
const mongoose = require('mongoose');
const app = express();
app.use(express.static('public'));
app.set('view engine','ejs');
app.use(bodyPasser.urlencoded({ extended: true }));
mongoose.set("strictQuery", false);
mongoose.connect('mongodb://localhost:27017/userDB',{useNewUrlParser:true})
.then(() => console.log('Connected!'));
const userSchema = {
email:String,
password:String
}
const User = new mongoose.model("User",userSchema);
app.get("/",(req,res)=>{
res.render("home")
})
app.get("/register",(req,res)=>{
res.render("register")
})
app.get("/login",(req,res)=>{
res.render("login")
})
app.post("/register",(req,res)=>{
const newUser = new User({
email: req.body.username,
password: req.body.password,
});
newUser.save((err)=>{
if(err){
console.log(err);
}else{
res.render("secrets")
}
})
})
app.post("/login",(req,res)=>{
const username = req.body.username;
const password = req.body.password;
User.findOne({email:username},(err,user)=>{
if(err){
console.log(err);
}else{
if(user){
if(user.password === password){
res.render("secrets")
}
}
}
})
})
app.listen(3000,function(){
console.log("port is statrt at 3000");
})

Related

How to send data from a form to mongodb?

I am created a nodejs project the structure of py project is:
api.js is:
const express = require('express');
const router = express.Router();
const add = require('../model/myModel');
router.get('/',function(req,res){
res.render('myForm');
});
router.post('/add', (req, res) => {
console.log(req.body)
n = req.body.name,
phone = req.body.phone,
console.log(`name = ${n}`)
let obj = new Address({
name: n,
phone: phone,
});
// add this instance to the database.
obj.save()
.then((address) => {
res.send(address);
})
.catch((err) => {
console.log(error);
});
});
module.exports = router;
and my app.js is:
const express = require('express');
const mongoose = require('mongoose');
const route = require('./route/api');
//Initialize express app
const app = express();
// Connecting to DB
const dbPath = 'mongodb://localhost:27017/testdb';
const dbOptions = {useNewUrlParser: true};
mongoose.connect(dbPath, dbOptions).then(()=>{
console.log(`We are connected to our database ${dbPath}`);
}).catch((error)=>{
console.log(`We are note able to connect to our database: ${error}`);
});
app.use(express.static('public'));
app.use(express.json());
app.set("view engine", "ejs");
// initialize routes
app.use("/api", route);
//Initialize the sever
app.listen(3000, () => {
console.log('sever listening on port:3000');
});
and myForm.ejs is:
So, I want to be able to enter the data in myForm.ejs and save this data in the database. But when I fill the form and press submit my req.Body is an empty object. Where is my error?
Server side you need additional parser middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true })); //add this line
Client side your form should use /api/add, and not /add

why my form data doesn't stored in database?

My app.js entire codes:
var express = require("express");
var app = express();
var port = 3000;
app.listen(port, () => {
console.log("Server listening on port " + port);
});
var mongoose = require("mongoose");
mongoose.Promise = global.Promise;
mongoose.connect("mongodb://localhost:27017/node-demo", { useNewUrlParser: true, useUnifiedTopology: true });
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
var nameSchema = new mongoose.Schema({
firstName: String,
lastName: String
});
var User = mongoose.model("User", nameSchema);
app.post("/addname", (req, res) => {
});
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post("/addname", (req, res) => {
app.post("/addname", (req, res) => {
var myData = new User(req.body.firstName, req.body.lastName);
myData.save()
.then(item => {
res.send("item saved to database");
})
.catch(err => {
res.status(400).send("unable to save to database");
});
})
});
This is my index.html file
<!DOCTYPE html>
<html>
<head>
<title>Intro to Node and MongoDB
</title>
</head>
<body>
<h1>Into to Node and MongoDB</h1>
<form method="post" action="/addname">
<label>Enter Your Name</label><br>
<input type="text" name="firstName" placeholder="Enter first name..." required>
<input type="text" name="lastName" placeholder="Enter last name..." required>
<input type="submit" value="Add Name">
</form>
</body>
<html>
After writing my code I open my mongod server than start mongo in other terminal then I run my app.js it worked properly it create server localhost:3000 then I went to my host I add my name in form and then submit, but it doesn't add to my database
Why this is not working?
My form data doesn't stored in my mongodb database. Please help me!
I think the body-parser library is deprecated on express 4 and later versions.
please use
app.use(express.json())
instead of body=parser.
not need to call any npm packages for parsing data from the form.
Here is the issue:
var myData = new User(req.body.firstName, req.body.lastName);
you have to pass an object to new User
var myData = new User( { firstName:req.body.firstName, lastName:req.body.lastName } );
i think i know what is wrong.
change app.use("/"... to app.get("/"...
bacause use handles all requests including POST. so when you send any request it sends the html file again and kills any other process.
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
I think you are not passing data correctly in the user model.
app.post("/addname", (req, res) => {
// make sure your request object is getting the same properties
var myData = new User(req.body.firstName, req.body.lastName);
myData.save()
.then(item => {
res.send("item saved to database");
})
.catch(err => {
res.status(400).send("unable to save to database");
});
});
As you updated the code for form, lastName is the fieldName. You should make the changes in the schema object too.
Also, Please check the request headers that comes in if it is of Accept:multipart/form-data then the bodyParser won't work instead you should use multer.
Some useful body parsers that you might need to consider if needed.
form-data: multer
x-www-form-urlencoded: express.urlencoded()
raw: express.raw()
json: express.json()
text: express.text()
Updated app.js file:
var express = require("express");
var app = express();
var port = 3000;
app.listen(port, () => {
console.log("Server listening on port " + port);
});
var mongoose = require("mongoose");
mongoose.Promise = global.Promise;
mongoose.connect("mongodb://localhost:27017/node-demo", { useNewUrlParser: true, useUnifiedTopology: true });
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
var nameSchema = new mongoose.Schema({
firstName: String,
lastName: String
});
var User = mongoose.model("User", nameSchema);
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post("/addname", (req, res) => {
var myData = new User(req.body.firstName, req.body.lastName);
myData.save()
.then(item => {
res.send("item saved to database");
})
.catch(err => {
res.status(400).send("unable to save to database");
});
});
Note: you have added two extra routes with same route handler, I have just removed it. Update this file in your project and run it.

Redirect to another url after post request (AJAX, EXPRESS)

As a part of learning node.js servers I'm working on a little log-in website. There's a site you can open and enter your username which will then be sent through an ajax post request to the server and saved into an array of all users. I wanna make it so that after you submit your username, you will be redirected to another page, unique for every username, where you will be able to see the information about you username. Sort of a 'manage your account' site.
However, I can't seem to figure out a way to redirect me to this page after I have submitted an username.
Say for example you submit a username 'kokot' and it's the 3rd username that's been submitted so far. Thus, in the 'players' array, your user object will look something like this {id: 2, username: 'kokot'}.
Now I want to redirect you to the url localhost:2000/players/2 to see the info about your specific username.
NODE JS
const express = require('express');
const server = express();
const bodyParser = require('body-parser');
server.use(bodyParser.urlencoded({extended: false}));
server.use(bodyParser.json());
let players = [];
//loads the home page
server.get('/', (req, res) =>{
res.sendFile(__dirname + '/home.html');
});
//loads the page with the list of players
server.get('/players', (req, res) =>{
res.send(players);
});
server.get('/player/:id', (req, res) =>{
res.send(players[req.params.id]);
});
//takes a new username and saves it to players array
server.post('/', (req, res) =>{
console.log('NEW PLAYER: ' + req.body.username);
players.push({
id: players.length,
username: req.body.username
});
});
/////////////////////////////////////////////////////////////////////////////
server.listen(2000, () => console.log('LISTENING ON PORT 2000'));
HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>Home</title>
</head>
<body>
<h1>PISKVOREC</h1>
<form id="userForm">
username
<input type="text" name="text" id="userFormInput">
<input type="submit" name="Submit" id="userFormSubmit">
</form>
<script>
$(document).ready(()=>{
let homeUrl = 'http://localhost:2000';
let $userForm = $('#userForm');
let $userFormSubmit = $('#userFormSubmit');
//submits a new username to the server
$userFormSubmit.click(() =>{
$.post(homeUrl, {
username: $('#userFormInput').val()
}, function(){
console.log('USERNAME SUBMITTED TO SERVER');
});
$.
});
////////////////////
});
</script>
</body>
</html>
Thank you for you responses and ideas
Have a nice day
Sure, see below:
server.post('/', (req, res) =>{
console.log('NEW PLAYER: ' + req.body.username);
players.push({
id: players.length,
username: req.body.username
});
res.redirect(`/player/${req.body.username}`);
});
UPDATE
Demo with vanilla Express.js app
app.js
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
app.post('/this', (req, res, next) => {
res.redirect(`/that/${req.body.username}`);
});
app.get('/that/:id', (req, res, next) => {
res.send(req.params);
});
module.exports = app;
index.hbs
<form method="post" action="/this">
<input id="username" name="username" value="vader" type="text" />
<button type="submit">Submit</button>
</form>
results in a redirect to: http://localhost:3000/that/vader

NodeJS - Express - Sessions - Redirect to secure page

I'm trying to set up a "backend" for a webpage I've created. So some pages can only be accessible if the user is logged in. I've built the basic functionality for this and I can do a simple validation in whether the user is logged-in. But the redirecting to the page is where I get stuck.
Example:
var auth = function(req,res,next){
if (req.session.loggedin){
return next();
} else{
return res.sendStatus(401);
}
};
app.get('/list-video', auth, function (req, res) {
res.redirect('/list-video');
});
So my issue is that '/list-video' is the page I want to protect and only be accessible when the user successfully logged in. But after the validation, I'm redirecting to the same page: '/list-video'. this doesn't seem to work as I'm obviously getting stuck in a loop. I have tried redirecting to a different page like '/list-audio' and of course this works fine.
Can someone advise on how this is usually done? Do I need to create a separate link that I can redirect to? (I do want to prevent users going to that link manually by typing the URL in the browser.)
Any help or advice will be greatly appreciated!
My complete app.js code:
const express = require('express');
const fileUpload = require('express-fileupload');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const path = require('path');
const app = express();
const session = require('express-session');
const { getHomePage } = require('./routes/index');
const { getBackendPage } = require('./routes/backend');
const { getVideoPage, listVideoPage, editVideoPage, editVideo, deleteVideo, addVideoPage, addVideo } = require('./routes/video');
const { getEbookPage } = require('./routes/ebook');
const { getMusicPage } = require('./routes/music');
const { getGamePage } = require('./routes/game');
const { getShopPage } = require('./routes/shop');
const port = 5000;
const db = mysql.createConnection({
host: '127.0.0.1',
user: 'user',
password: 'bla',
database: 'test'
db.connect((err) => {
if (err) {
throw err;
}
console.log('Connected to database');
});
global.db = db;
// configure middleware
app.set('port', process.env.port || port); // set express to use this port
app.set('views', __dirname + '/views'); // set express to look in this folder to render our view
app.set('view engine', 'ejs'); // configure template engine
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); // parse form data client
app.use(express.static(path.join(__dirname, 'public'))); // configure express to use public folder
app.use(fileUpload()); // configure fileupload
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true
}));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
/ passenger views
app.get('/', getHomePage);
app.get('/backend', getBackendPage);
app.get('/video', getVideoPage);
app.get('/ebook', getEbookPage);
app.get('/music/:id', getMusicPage);
app.get('/game', getGamePage);
app.get('/shop', getShopPage);
// backend views video
app.get('/edit-video/:id', editVideoPage);
app.post('/edit-video/:id', editVideo);
app.get('/add-video', addVideoPage);
app.post('/add-video', addVideo);
app.get('/delete-video/:id', deleteVideo);
// login screen
app.post('/auth', function (request, response) {
var username = request.body.username;
var password = request.body.password;
if (username && password) {
db.query('SELECT * FROM accounts WHERE username = ? AND password = ?', [username, password], function (error, results, fields) {
if (results.length > 0) {
request.session.loggedin = true;
request.session.username = username;
response.redirect('/');
} else {
response.send('Incorrect Username and/or Password!');
}
response.end();
});
} else {
response.send('Please enter Username and Password!');
response.end();
}
});
var auth = function(req,res,next){
if (req.session.loggedin){
return next();
} else{
return res.sendStatus(401);
}
};
app.get('/list-video', auth, function (req, res) {
res.redirect('/list-video');
});
app.listen(port, () => {
console.log(`Server running on port: http://localhost:${port}`);
});
Move your protected pages to a different directory (outside the folder where your public static files are) and serve the express.static after the authentication middleware, something like this:
app.use('/', express.static(path.join(__dirname, 'public'))); //notice I have no auth middleware
app.use('/mysecretpages', auth, express.static(path.join(__dirname, 'secret'))); //notice I DO have auth middleware
change it to:
var auth = function(req,res,next){
if (!req.session.loggedin){
return res.redirect("/login");
} else{
return next();
}
};
app.get('/list-video', auth);
That way you will redirect to the login page if the user isn't authenticated and continue if he is.

Express request doesn't end

i made a very simple api using express.js. Here's the code:
var express = require('express');
var app = express();
var morgan = require('morgan');
var UserModel = require('../Models/User')
app.use(morgan('short'));
app.use(express.json());
app.get('/getAll', (req, res) => {
res.status(200).json({auth: true});
})
app.post('/addUser', (req, res) => {
const { name, email, password } = req.body;
UserModel.create({name, email, password}, (err, user) => {
if(err) return res.status(500).end({auth: false})
res.status(200).end({user});
});
});
module.exports = app;
And here's the userModel:
const mongoose = require("mongoose")
const Schema = mongoose.Schema;
const UserSchema = new Schema(
{
name: String,
email: String,
password: String,
},
{timestamps: false}
);
mongoose.model("User", UserSchema);
module.exports = mongoose.model("User");
This is the main server.js file:
var express = require('express');
var app = express();
const AuthController = require("./Controllers/AuthController");
const PORT = 3001;
app.use("/api/auth", AuthController);
app.listen(PORT, () => console.log(`Listening on port ${PORT}..`))
This is the db.js file:
const mongoose = require('mongoose');
const dbRoute = "mongodb://<user>:<password>#<stuff>/nodejs-db";
mongoose.connect(
dbRoute,
{useNewUrlParser: true}
);
So here's the problem. when i try to make a request to this api using Insomnia, the requests doesn't end. Basically Insomia starts sending the request and i have to wait like 20 secs until i get something on my express terminal. If i end the request manually i get this:
::ffff:127.0.0.1 - POST /api/auth/addUser HTTP/1.1 - - - - ms
I tried looking online but couldn't find anything useful.
I come from a django backgrond. I'm new to Node and Express js.
Edit:
The problem is only with the posts requests because whenever i make a get request it returns immediately {auth: true}.
Change your .end() to .send()
app.post('/addUser', (req, res) => {
const { name, email, password } = req.body;
UserModel.create({name, email, password}, (err, user) => {
if(err) return res.status(500).send({auth: false})
res.status(200).send({user});
});
});
I solved this problem.
Apparently the problem was that my db connection was on another file.
All i did was to move the content from the db.js file to my server.js file.
I forgot to include my db file.

Categories