I have a db operation in login post router, when db operation callback success, I got a username value, and how I can pass this username to the "/" router?
router.post('/login', (req, res)=> {
var username = req.body.username;
var password = common.md5(req.body.password + common.MD5_SUFFIX);
db.query(`SELECT * FROM admin_table WHERE username='${username}'`, (err, data)=> {
if (err) {
console.log(err);
res.status(500).send('database error').end();
} else {
if (data.length == 0) {
res.status(404).send('no this admin').end();
} else {
if (data[0].password == password) {
req.session['admin_id']=data[0].ID;
res.redirect('/');
} else {
res.status(404).send('This password is not incorrect!').end();
}
}
}
});
});
router.get('/login',(req,res)=>{
res.render('admin/login.ejs',{layout:'/admin/layout.ejs',title:'Login'});
});
router.get('/',(req,res)=>{
res.render('admin/index.ejs',{layout:'/admin/layout.ejs',title:'Index',username:username});
});
Such as in post login router, I got a username is "ollie", when db operation is ending, the router redirect "/", I can got the username "ollie" in the "/" router .
The simplest way is to use a session. E.g. where you configure the express app, use this:
if (data[0].password == password) {
req.session['admin_id']=data[0].ID;
req.session.username = data.username;
res.redirect('/');
}
Then later you can access that, e.g.
router.get('/route', (req, res) => {
console.log(req.session && req.session.username);
res.end(`Hi ${req.session && req.session.username}`)
});
And please, please, please do not use md5 in any authentication schemes, even example code.
Related
My user session does not persist within the server. I can see within the log that I saved it in my /login route, but when I try to access it from a different route, its "undefined".
My /login route:
app.route("/login")
.post(async (req, res) => {
var username = req.body.username,
password = req.body.password;
console.log('\t we are here')
try {
var user = await User.findOne({ username: username }).exec();
if(!user) {
res.redirect("/login");
}
user.comparePassword(password, (error, match) => {
if(!match) {
console.log('Password Mismatch');
console.log('Ensure redirect to /login');
res.redirect("/login");
}
});
req.session.user = user;
console.log('\t\treq.session:');
console.log(req.session)
var redir = { redirect: "/dashboard" };
return res.json(redir);
} catch (error) {
console.log(error)
}
});
In the above snippet I try to save the session data by req.session.user = user;. Its log appears as:
But now when I try to call the session I just stored, it shows "undefined". This is my /dashboard route & its corresponding log:
app.get("/dashboard", (req, res) => {
console.log(req.session.user_sid);
// console.log(req.cookies.user_sid);
if (req.session.user && req.cookies.user_sid) {
// res.sendFile(__dirname + "/public/dashboard.html");
console.log(req.session);
res.send("send something")
} else {
res.send("go back to /login");
}
});
To my understanding, user authentication is done my checking sessions and cookies, which is why I'm trying to save the session to request.session. I want to the data to persist so that I can use it in all my other routes such as when calling /dashboard api.
Dashboard api will be call by a protected route like when the user is logged in.
It appears as though when I sign into my application, it is storing the credentials locally on the EC2 server. I've quadruple checked my code and I can't figure out what the deal is. If KEVIN signs in from any device, the next user to sign in, or if someone refreshes their page they end up signed in as KEVIN. I am including all code that could potentially be involved in the issue. Outside of this problem, all of my interaction with cognito works great; no errors & no problems. Any help would be greatly appreciated. I am using Node.js, Express, AWS, and Websockets on my EC2 Instance.
// Accessed from server for route authentication before page render or redirection
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
module.exports = {
ensureAuthenticated: function(req, res, next) {
let data = { UserPoolId : 'us-east-1_7xUGRJPKq',
ClientId : '6glign6b34c806osfhnik18cb3'
};
let userPool = new AmazonCognitoIdentity.CognitoUserPool(data);
let cognitoUser = userPool.getCurrentUser();
console.log(`ensuring authentication....`);
console.log(cognitoUser);
if (cognitoUser === null) {
req.flash('error_msg', 'Please log in');
res.redirect('/login');
} else {
cognitoUser.getSession((err, session) => {
if (err) {
console.log(err);
} else {
next();
}
});
}
},
};
// Routes where I am seeing the problem
const express = require('express');
const router = express.Router();
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const { ensureAuthenticated } = require('../config/auth.js');
router.get('/', (req, res) => {
res.redirect('/dashboard');
});
router.get('/dashboard', ensureAuthenticated, (req, res) => {
res.render('dashboard', {
layout: './layouts/dashboard-layout.ejs'
});
});
// Login authentication
router.post('/login', (req, res) => {
const loginDetails = {
Username: req.body.email,
Password: req.body.password
}
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(loginDetails);
const userDetails = {
Username: req.body.email,
Pool: userPool
}
const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userDetails);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: data => {
cognitoUser.getUserAttributes(function(err, result) {
if (err) {
console.log(err);
return;
} else {
console.log('LOGIN RESULTS')
console.log(result[0].Value.toString());
let userId = result[0].Value.toString();
let userCity = result[2].Value.toString();
console.log(userId);
console.log(userCity);
res.redirect(`/dashboard/${userCity}/${userId}/`)
};
});
},
onFailure: err => {
req.flash('error_msg', 'Invalid Credentials');
console.error(err);
res.redirect('/login');
}
})
});
Thank You!
UPDATE 10/21/19: Removed function that doesn't apply to the issue.
Also do not seem to have any JWT in local storage:
Click Here for image
I would like to query my Redis server for a username's matching password. How can I do this? I have very little experience with both Redis and Node so I wasn't able to find the key that stores such.
Any help is well appreciated!
Look in file /src/routes/authentication.js. There you have Auth.login function which get username, password as parameters. Then you have getUidByUserslug function on user object which is call at first and returns you userID (_uid) from redis hash called 'userslug:uid' (look in /src/user.js file db.getObjectField('userslug:uid', userslug, callback); function). Next step is getting user by user ID from 'user:' + uid hash, stored in redis. This is done using db.getObjectFields('user:' + uid, ['password', 'banned'], next); function in authenticate.js file.
The following is Auth.login function:
Auth.login = function(req, username, password, next) {
if (!username || !password) {
return next(new Error('[[error:invalid-password]]'));
}
var userslug = utils.slugify(username);
var uid;
async.waterfall([
function(next) {
user.getUidByUserslug(userslug, next);
},
function(_uid, next) {
if (!_uid) {
return next(new Error('[[error:no-user]]'));
}
uid = _uid;
user.auth.logAttempt(uid, req.ip, next);
},
function(next) {
db.getObjectFields('user:' + uid, ['password', 'banned'], next);
},
function(userData, next) {
if (!userData || !userData.password) {
return next(new Error('[[error:invalid-user-data]]'));
}
if (userData.banned && parseInt(userData.banned, 10) === 1) {
return next(new Error('[[error:user-banned]]'));
}
Password.compare(password, userData.password, next);
},
function(passwordMatch, next) {
if (!passwordMatch) {
return next(new Error('[[error:invalid-password]]'));
}
user.auth.clearLoginAttempts(uid);
next(null, {uid: uid}, '[[success:authentication-successful]]');
}
], next);
};
How do I make it so that if a response has been sent back, then no more responses should be sent? Actually, the issue is that if a response is sent back, then express (or nodejs) shouldn't continue running through the rest of the code.
I've tried doing next() but terminal throws the error of next() being undefined. res.end() doesn't seem to work either?
routing.js:
router.post('/user/create', function(req, res, next) {
user.createUser(req, res);
});
user.js createUser
user.prototype.createUser = function(req, res, next) {
var body = req.body;
checkAllInput(body, res, next);
// do some more checks then finally create user
}
user.js createUser
function checkAllInput(body, res, next) {
checkError.checkUsername(body, res, next);
checkError.checkPassword(body, res, next);
}
checkError.js
userClass.prototype.checkUsername = function(username, res) {
if (!username || username === "bob) {
res.status(406).send("username");
}
}
userClass.prototype.checkPassword = function(password, res) {
if (!password || password === "hello") {
res.status(406).send("password");
}
}
Call createUser in routing, which then calls checkAllInput which calls checkUsername but should stop if username sends a response back.
You need to return, so the code stops there. Otherwise it will keep on going.
userClass.prototype.checkUsername = function(username, res) {
if (!username || username === "bob) {
return res.status(406).send("username");
}
}
userClass.prototype.checkPassword = function(password, res) {
if (!password || password === "hello") {
return res.status(406).send("password");
}
}
next() isn't inherent in the code, it has to be defined somewhere, and even if it is, it still doesn't stop the code as it is asynchronous.
I'm assuming you're using Express. You might want to do this with middleware.
//middleWare.js
exports.checkUserModel = function (req, res, next) {
var body = req.body,
username = body.username,
password = body.password,
if (!username || username === "bob) {
return res.status(406).send("username required");
}
if (!password || password === "hello") {
return res.status(406).send("password required");
}
next();
}
//router.js
var middleWare = require('./middleWare');
var user = require('./controllers/users');
app.post('/user/createUser', middleWare.checkUserModel, user.create);
You want to use the express middleware like so :
checkUsername = function(req, res, next) {
if (checkUserNameIsValid) {
//check the password
next()
}
else{
///otherwise return
res.status(406).send("username");
}
}
checkPassword = function(req, res, next) {
if (checkIfPasswordIsValid) {
//create the user when password is valid too
next();
}
else {
//else return response
res.status(406).send("password required");
}
}
createUserIfPasswordAndUserNameIsOk = function(req, res, next){
//create the user here
}
Add in sequence you want to handle the request.
router.post('/user/create', checkUserName, checkPassword, createUserIfPasswordAndUserNameIsOk );
So what will happen the express router will first call checkUserName and if you don't call next() then it returns. So if you call next() in it it will call the next method in for the current requested resource which is checkPassword. And so on.
Take a look at Having a hard time trying to understand 'next/next()' in express.js thread.
Note that you don't have to use return. Also take a look at #Brian answer
i have reference for http://blog.modulus.io/nodejs-and-express-basic-authentication
my code conect my database mongodb:
var admin = express.basicAuth(authentikasi);
function authentikasi(user, pass, callback) {
// declrare my database mongodb
db.collection('ak_admin', function (err, data) {
data.findOne({'adm_name': {'$regex': user}}, function (err, level) {
if (level == null) {
console.log('Nilai database Administrator masuk Null ulangi login');
callback(null);
} else {
var a = level.adm_name;
var b = level.adm_password;
var c = level.adm_mobile;
if (user === a && pass === b) {
callback(null, {name: a, id: c});
} else
callback(null, false);
}
});
});
};
app.get('/admin', admin, function(req, res){
res.sendfile(__dirname + '/admin/index.html');
});
my schema for login basicauth is succesfull but my question : how to create logout because my site admin have login after use this schema not input username and password again :
app.get('/logout', function(req, res){
//how code in here for erase memory in variable admin (user and pass)
res.sendfile(__dirname + '/public/index.html');
});
please help me thanks you...