Ask for a password to show a page - html

I've made a very simple website with 1 page (main.html) just to put my Curriculum Vitae.
But to avoid all people seeing it I just want to ask for a password (i dont even need a username).
Is there a simple way to do this? It can be something like an alert asking for a password or something like that.
I'm trying this:
//Init App
const app = express();
//Auth
var preAuth = require('http-auth');
var basic = preAuth.basic({
realm: "Restricted Access. Please login to proceed."
}, function (username, password, callback) {
callback( (username === "user" && password === "password"));
}
);
app.use(preAuth.connect(basic));
//View Engine
app.set('views', path.join(__dirname, 'views'));
app.engine('html', engines.mustache);
app.set('view engine','html');
//Home route
app.get('/', function (req,res) {
res.render('main');
});

Please try it this way to see if it works correctly
// Authentication module.
var express = require('express');
var httpAuth = require('http-auth');
var authentication = httpAuth.basic({
realm: "Type your username and password."
}, (username, password, callback) => {
callback(username == 'root' && password.trim() == 'toor');
});
var app = express();
app.use(httpAuth.connect(authentication));
// Setup route.
app.get('/', (req, res) => {
res.send(`Hello from express - ${req.user}!`);
});
app.listen(3030);
The session data would be "root" (as a user) and "toor" (as a password).
Apparently the problem is the way you are using for the implementation of http-auth

Related

How can I stop my user login in page from logging in without details?

Hi I'm creating an API which requires a log in system using NodeJs and a mySQL database.
I've managed to connect to my database and create a basic login page for now. However, on my log in page without even typing anything in and just pressing the log in button it redirects straight to the welcome page.
How can I fix my code so that a user has to type the correct username and password for it to log in ?
In my database the table is called users and I want to use the columns called username and password.
This is my code so far,
code currently using
const mysql = require("mysql2");
const express = require ("express");
const bodyParser = require("body-parser");
const encoder = bodyParser.urlencoded();
const app = express();
app.use("/assets",express.static("assets"));
const connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "root123",
database: "mydb"
});
connection.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
console.log('Connected to the MySQL server.');
});
app.get("/", function(req,res){
res.sendFile(__dirname + "/index.html");
})
app.post("/", encoder,function(req,res){
var username = req.body.username;
var password = req.body.password;
connection.query("select*from users where username =
users.username and password = users.password ",
[username, password],function(error,results,fields){
if (results.length > 0) {
res.redirect("/welcome");
} else {
res.redirect("/");
}
res.end();
})
})
app.get("/welcome",function(req,res){
res.sendFile(__dirname +'/welcome.html')
})
app.listen(4500);
There are lots of problems with this code, but your current issue is that your query is not checking their stored username and password against what they are typing in, it is checking them against themselves

Express session not saving after successful authentication

I am implementing a login system for my project. This project is divided in two, a server portion in NodeJS, and a client portion in ReactJS. Both of these are wrapped up in docker containers including a couple more containers for mySQL and PHPMyAdmin. Thus far, I've been able to connect to databases in the mySQL container and insert into a table for Users. Now, I'm trying to log in with a user, then save this user information if the login is successful, and return the session when asked. So I call the sign in get request as follows in the front-end:
export function signIn(table, userName, password) {
return axios.get(`http://localhost:8000/signin`, {
params: {
table,
userName,
password,
},
}, {withCredentials: true}).then((response) => {
if (response.data.length === 1) {
return "success";
}
return response;
});
}
Then in the server, I receive and work with the information like this:
const bcrypt = require('bcryptjs');
const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const multer = require('multer');
const mysql = require('mysql');
const nodeMailer = require('nodemailer');
const session = require('express-session');
const smtpTransport = require('nodemailer-smtp-transport');
const app = express();
const upload = multer();
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000,
secure: false,
}
}));
app.use(cors(({
credentials: true,
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
const pool = mysql.createPool({
host: process.env.MYSQL_HOST_IP,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
});
app.get('/signin', (req, res) => {
const { table, userName, password } = req.query;
pool.query(`select * from ${table} where username = '${userName}'`, (err, results) => {
if (err) {
res.send(err);
} else {
if (bcrypt.compareSync(password, results[0].password)) {
req.session.userId = results[0].id;
req.session.name = results[0].name;
req.session.email = results[0].email;
req.session.sex = results[0].sex;
req.session.img = results[0].img;
req.session.userName = results[0].username;
req.session.about = results[0].about;
req.session.save(err => console.log(err));
res.send(results);
} else {
res.send([]);
}
}
});
});
Then I expect to call it with another request to get the information back and use to to modify a front end component's state like this (both of these requests are in the same file):
app.get('/loggeduser', (req, res) => {
if (req.session.userId) {
const {
userId,
name,
email,
sex,
img,
userName,
about,
} = req.session;
const userInfo = {
userId,
name,
email,
sex,
img,
userName,
about,
};
res.send(userInfo);
} else {
res.send({});
}
});
and the component calls it like this:
export function getLoggedUser(setUserInfo) {
axios.get(`http://localhost:8000/loggeduser`, {}, {withCredentials: true}).then((response) => {
setUserInfo(response.data);
});
}
But the information never gets sent back, because req.session.userId is always undefined. I tried adding a console.log to output req.session and whenever I refresh the page (at which time the component calls getLoggedUser) the server image outputs req.session with a created time that is just a few seconds ago from the moment I refresh the page, meaning it gets created anew whenever I refresh. Is it that this is not saving properly because it's a get request and not a route? Please let me know if I may be missing something vital for this to work.

Keep getting CANNOT POST /login everytime i login

I got the codes from a tutorial, seems to work fine until I made routers since I'm trying to create an E-commerce website with a login system.
This is my index.js code
const express = require('express');
const app = express();
const prodRouter = require('./server/routes/prodRouter');
const loginRouter = require('./server/routes/loginRouter');
const regRouter = require('./server/routes/regRouter');
const contRouter = require('./server/routes/contRouter');
const checkRouter = require('./server/routes/checkRouter');
const profRouter = require('./server/routes/profRouter');
const path = require('path'); const port = 3500;
app.use(express.static('public'));
app.set('views', path.join(__dirname, 'server/views'));
app.set('viewengine', 'pug');
app.use('/prod', prodRouter);
app.use('/login',loginRouter);
app.use('/reg', regRouter);
app.use('/cont',contRouter);
app.use('/check', checkRouter);
app.use('/profile',profRouter);
app.get('/', (req, res) =>{res.render('Home.pug', {}); });
app.listen(port, (err) => { // arrow function feature from ES6 if(err){ console.log(err); }
console.log(`Listening to port ${port}!`); });
and loginRouter.js
const express = require('express'); const router = express.Router();
const app = express();
const mysql = require('mysql');
const server = require('http').createServer(app);
bodyParser = require('body-parser');
const connection = mysql.createConnection({
host: 'localhost',
database: 'login',
user: 'root',
password: '',
});
users = []; connections = [];
router.get('/', (req, res) => {
res.render('login', {});
});
app.use(bodyParser.urlencoded({
extended: true
});
app.use(bodyParser.json());
connection.connect();
app.post('/', function(req, res){
var email= req.body.email;
var password = req.body.password;
connection.query('SELECT * FROM user WHERE email = ?',[email],function (error, results, fields) {
if (error) {
// console.log("error ocurred",error);
res.send({
"code":400,
"failed":"error ocurred"
})
}else{
// console.log('The solution is: ', results);
if(results.length >0){
if([0].password == password){
return res.redirect('/profile');
}else{
res.send({
"code":204,
"success":"Email and password does not match"
});
}
}else{
res.send({
"code":204,
"success":"Email does not exits"
});
}
}
});
enter code here
});
module.exports = router;
my pug form:
form#login-form(method='post')
fieldset.input
p#login-form-username
label(for='modlgn_username') Email
input#modlgn_username.inputbox(type='text', name='email', size='18', required)
p#login-form-password
label(for='modlgn_passwd') Password
input#modlgn_passwd.inputbox(type='text', name='password', size='18', required)
.remember
p#login-form-remember
label(for='modlgn_remember')
a(href='#') Forget Your Password ?
input.button(type='submit', value='Sign In')
I'm pretty sure I did something wrong with the router, because every time I login, I keep getting CANNOT POST instead of going to the profile page.
Any help would be greatly appreciated.
EDIT: I added my pug code for form.
EDIT: the problem only occurs if the login page is not the main page.
example:
login page > *logs in > profile - no problem
home page > login page > *logs in > profile - error
This is happening because you don't have an action on your form (see this article for details). When you don't have an action the form is submitted to the URL it lives at, so if you POST on your home page without an action the post will go to /home.
Change the form element to look like this:
form#login-form(method='post' action='/login')

Best practices for MySQL + Node/Express + Angular Stack

I am currently using MySQL for the db instead of the popular mongodb, since that is the case there isn't much documentation out there as far as architecture and getting set up. This is my current structure
client
-- angular files
routes
-- index.js
views
-- 404 page
app.js
I don't understand how I can implement controllers or models into this structure. I'm currently grabbing data from the db or sending it with the routes..I'm not sure what the added layer of controllers would do. Maybe this is a dumb question but I would just like to have a clear baseline so that my project will scale well. I feel like there should be way more to this than what I currently have.
index.js
const express = require('express');
const mysql = require('mysql');
const router = express.Router();
const db = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'password',
database : 'db'
});
// Connect
db.connect((err) => {
if(err){
throw err;
}
console.log('MySql Connected...');
});
// Select Data
router.get('/getData', (req, res) => {
let sql = 'SELECT * FROM data';
let query = db.query(sql, (err, results) => {
if(err) throw err;
console.log(results);
res.send(results)
});
});
module.exports = router;
app.js
const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser');
const path = require('path');
const cors = require('cors');
const compression = require('compression');
const helmet = require('helmet')
const expressSanitizer = require('express-sanitizer');
const index = require('./routes/index');
const app = express();
const port = 3000;
var corsOptions = {
origin: 'http://localhost:8100',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
// var logger = (req, res, next) => {
// console.log('logging...')
// next();
// }
//added security
app.use(helmet())
// //set logger
// app.use(logger)
//cors options
app.use(cors(corsOptions))
//body parser middleware
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
// Mount express-sanitizer here
app.use(expressSanitizer()); // this line follows bodyParser() instantiations
//set static path
app.use(express.static(path.join(__dirname, 'client')));
// set our default template engine to "ejs"
// which prevents the need for using file extensions
app.set('view engine', 'ejs');
//gzip compression
app.use(compression())
//set views for error and 404 pages
app.set('views', path.join(__dirname, 'views'));
app.use('/', index);
app.use('/fp/trips', trips);
app.listen(port, () => {
console.log('server started on port 3000')
})
When working on Node apps I tend to favor a scheme where controllers are (almost) services -- I think it works really well for small applications.
This is an example:
index.js
let app = express()
let users = require('./services/users')
app.get('/users/:id', async function(req, res, next) => {
try {
res.json(users.getByid(req.params.id))
} catch() {
next(err)
}
})
app.listen(8080)
services/users.js
let db = require('./db')
async function getById(id) {
let conn = await db.connect()
let user = conn.query('SELECT * FROM user WHERE id = ?', [id])
if (!user) {
throw new Error("404")
}
return user
}
module.exports = {getById}
services/db.js
let realDb = require('some-open-source-library-to-interact-with-db')
realDb.initialize(process.env.DB_CREDENTIALS) // pseudo-code here
module.exports = realDb
This though, won't work well when you're building large, complex apps -- I think you will require more structure in that case.
PS: I wouldn't suggest to build a large, complex app ever -- split it into smaller ones where patterns like the one I presented work nicely.
You can use Sequelize as ORM (Object Relational Mapper) for your MySQL DB to make your code more readable and to allow you to create better structure of your app. It also has support for PostgreSQL, MySQL, MariaDB, SQLite, and MSSQL.
There are samples out there how to integrate Sequelize with Express. I'm not sure if I'm allowed to post a github repository here but here it is:
https://github.com/jpotts18/mean-stack-relational
PS. I don't own this repository but this might help you somehow.

NodeJS sessions, cookies and mysql

I'm trying to build an auth system and I have app.js
var express = require('express')
, MemoryStore = require('express').session.MemoryStore
, app = express();
app.use(express.cookieParser());
app.use(express.session({ secret: 'keyboard cat', store: new MemoryStore({ reapInterval: 60000 * 10 })}));
app.use(app.router);
and the route.index as
var express = require('express')
, mysql = require('mysql')
, crypto = require('crypto')
, app = module.exports = express();
app.get('/*',function(req,res){
var url = req.url.split('/');
if (url[1] == 'favicon.ico')
return;
if (!req.session.user) {
if (url.length == 4 && url[1] == 'login') {
var connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'pass',
});
var result = null;
connection.connect();
connection.query('use database');
var word = url[3];
var password = crypto.createHash('md5').update(word).digest("hex");
connection.query('SELECT id,level FROM users WHERE email = "'+url[2]+'" AND password = "'+password+'"', function(err, rows, fields) {
if (err) throw err;
for (i in rows) {
result = rows[i].level;
}
req.session.user = result;
});
connection.end();
}
}
console.log(req.session.user)
when I access http://mydomain.com/login/user/pass a first time it shows in the last console call but a second time access the cookie is clean
Why do you not just use Express's session handling? if you use the express command line tool as express --sessions it will create the project template with session support. From there you can copy the session lines into your current project. There more information in How do sessions work in Express.js with Node.js? (which this looks like it may be a duplicate of)
As for sanitizing your SQL, you seem to be using the library, which will santitize your inputs for your if you use parameterized queries (ie, ? placeholders).
Final thing, you are using Express wrong (no offence). Express's router will let you split alot of your routes (along with allowing you to configure the favicon. See Unable to Change Favicon with Express.js (second answer).
Using the '/*' route will just catch all GET requests, which greatly limits what the router can do for you.
(continued from comments; putting it here for code blocks)
Now that you have an app with session support, try these two routes:
app.get('/makesession', function (req, res) {
req.session.message = 'Hello world';
res.end('Created session with message : Hello world');
});
app.get('/getsession', function (req, res) {
if (typeof req.session.message == 'undefined') {
res.end('No session');
} else {
res.end('Session message: '+req.session.message);
}
});
If you navigate in your browser to /makesession, it will set a session message and notify you that it did. Now if you navigate to /getsession, it will send you back the session message if it exists, or else it will tell you that the session does not exist.
You need to save your cookie value in the response object:
res.cookie('session', 'user', result);
http://expressjs.com/api.html#res.cookie