Route separation in express routing with passing passport instance - javascript

I'm trying to add user-login module to an existing app in node. It is using separate route files for each module and one main route file to use all the child routes which is ultimately used in server.js
When I try to pass passport instance to the user route, it gives me error as passport is not defined. Here is my app code and structure:
app
views
user
index.ejs
login.ejs
signup.ejs
profile.ejs
routes
docs
index.js
user
index.js
index.js
config
passport.js
server.js
server.js
const express = require('express')
const app = express()
const path = require('path')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const passport = require('passport')
const flash = require('connect-flash')
const session = require('express-session')
const routes = require('./routes/')
const port = process.env.PORT || 3000;
app.use(express.static(path.join(__dirname, 'public')));
require('./config/passport')(passport);
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(session({ secret: '********' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use('/', routes)(app,passport);
const server = app.listen(port, function(){
console.log('Server listening on port '+port);
});
config/passport.js
var LocalStrategy = require('passport-local').Strategy;
const sql = require('mssql')
const bcrypt = require('bcrypt-nodejs')
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function (username, done) {
done(null,username);
});
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
process.nextTick(function() {
var strSQL = "SELECT count(id) as uCount FROM <tbl> WHERE username = '"+email+"'";
var cb1 = function(err,recordset){
if(recordset[0].uCount>0){
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else{
var strSQL1 = "INSERT INTO <tbl>(username, password) VALUES('"+email+"','"+generateHash(password)+"')";
var cb2 = function(err,recordset){
return done(null, recordset,req.flash('signupMessage', 'Email registered successfully.'));
};
executeQuery(strSQL1,'INSERTION','<tbl>',cb2);
}
};
executeSelection(strSQL,'SELECTION','<tbl>',cb1);
});
}));
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
var strSQL = "SELECT a.count, id, username, password FROM <tbl> c , (SELECT COUNT(dbid) count FROM <tbl> b WHERE b.username = '"+email+"' ) a WHERE c.username = '"+email+"'";
var cb1 = function(err,recordset){
if(recordset[0].uCount <= 0){
return done(null, false, req.flash('loginMessage', 'No user found.'));
}
if (!validPassword(password,recordset[0].password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, recordset[0]);
};
executeSelection(strSQL,'SELECTION','<tbl>',cb1);
}));
};
executeSelection = function(strSQL, operationType, tableName, cb){
var request = new sql.Request(connection);
request.query(strSQL,function(err,recordset) {
if(err){
logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
}
logger.info(operationType+' ON '+tableName+' successful!');
cb(err,recordset);
});
};
executeQuery = function(strSQL, operationType, tableName, cb,validateClient) {
var request = new sql.Request(connection);
request.query(strSQL,function(err, recordset) {
if(err){
logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
}
logger.info(operationType+' ON '+tableName+' successful!');
if(cb){
cb(validateClient);
}
});
};
generatePasswordHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
validatePassword = function(curPass, dbPass) {
return bcrypt.compareSync(curPass, dbPass);
};
routes/index.js
const mainroute = require('express').Router()
/* ---- other existing routes included ---- */
const r_docs = require('./docs')
const r_user = require('./user') /*my custom route*/
/* ---- all other routes ---- */
mainroute.use('/docs', r_docs);
mainroute.use('/user', r_user)(app, passport); /*my custom route*/
mainroute.get('/', function(req, res){
res.render('home');
});
module.exports = function(app, passport){
mainroute;
}
routes/user/index.js
const express = require('express')
const router = express.Router()
router.get('/', function(req, res) {
res.render('user/index.ejs');
});
router.get('/login', function(req, res) {
res.render('user/login.ejs', { message: req.flash('loginMessage') });
});
// process the login form
router.post('/login', passport.authenticate('local-login', {
successRedirect : '/profile',
failureRedirect : '/login',
failureFlash : true
}));
router.get('/signup', function(req, res) {
res.render('user/signup.ejs', { message: req.flash('signupMessage') });
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile',
failureRedirect : '/signup',
failureFlash : true
}));
router.get('/profile', isLoggedIn, function(req, res) {
res.render('user/profile.ejs', {
user : req.user
});
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
module.exports = function(app, passport) {
router;
}
Please suggest what am I doing wrong here. Thanks

You should wrap your main and user routes to run their logic when you call them and at end return prepared route:
routes/index.js
module.exports = function(app, passport) {
const mainroute = require('express').Router()
/* ---- other existing routes included ---- */
const r_docs = require('./docs');
const r_user = require('./user'); /*my custom route*/
/* ---- all other routes ---- */
mainroute.use('/docs', r_docs);
mainroute.use('/user', r_user)(app, passport); /*my custom route*/
mainroute.get('/', function(req, res) {
res.render('home');
});
return mainroute;
};
routes/user/index.js
module.exports = function(app, passport) {
const express = require('express');
const router = express.Router();
router.get('/', function(req, res) {
res.render('user/index.ejs');
});
router.get('/login', function(req, res) {
res.render('user/login.ejs', {
message: req.flash('loginMessage')
});
});
// process the login form
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true
}));
router.get('/signup', function(req, res) {
res.render('user/signup.ejs', {
message: req.flash('signupMessage')
});
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/profile',
failureRedirect: '/signup',
failureFlash: true
}));
router.get('/profile', isLoggedIn, function(req, res) {
res.render('user/profile.ejs', {
user: req.user
});
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
return router;
};

You need to require it at the top of your user/index.js. Simply:
var passport = require('passport');
Then to make sure the user is authenticated:
router.get('/some/path', isLoggedIn, function(req, res) {
var user = req.user;
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}

Related

Cant figure out why my logout not logging out

When I'm trying to get to http://localhost:7000/logout, the URL redirects me to the main page. And it doesn't sign me out from my Google account. I want to show message "You are logged out" and then I want this code to ask user to log in again.
const express = require('express');
const session = require('express-session');
const passport = require('passport');
require('./auth');
const app = express();
function isLoggedIn(req, res, next) {
req.user ? next() : res.sendStatus(401);
}
app.use(session({ secret: 'cats', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.get('/', (req, res) => {
res.send('Authenticate with Google');
});
app.get('/auth/google',
passport.authenticate('google', { scope: [ 'email', 'profile' ] }
));
app.get('/google/callback',
passport.authenticate('google', {
successRedirect: '/protected',
failureRedirect: '/auth/failure',
})
);
app.get('/auth/failure', (req, res) => {
res.send('something went wrong..');
});
app.get('/protected', isLoggedIn, (req, res) => {
res.send(`Hello ${req.user.displayName}`);
});
app.get('/logout', function(req, res, next) {
req.logout(function(err) {
if (err) { return next(err); }
res.redirect("/");
});
});
app.listen(7000, () => console.log('listening on port: 7000'))

how to make a page only accessible when logged in with express & ejs

Currently I'm working on a little project for a dummy login/register page and now I want to add a page that is only accessible when you're logged in. So the question is how do I make a session or cookie and retrieve them? And how do I block not logged in users.
I'm currently using this code for the 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 mongoose = require('mongoose');
var expressSession = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var AuthTokenStrategy = require('passport-auth-token').Strategy;
require('./models');
var User = mongoose.model('User')
mongoose.connect('mongodb://localhost:27017/my-data', { useNewUrlParser: true, useUnifiedTopology: true })
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
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')));
passport.use(new LocalStrategy({
usernameField: "key"
}, function(key, next) {
User.findOne({
key: key
}, function(err, user) {
if (err) return next(err);
if (!user) {
return next({message: 'Key incorrect'})
}
next(null, user);
})
}));
passport.serializeUser(function (user, next) {
next(null, user._id)
})
passport.deserializeUser(function (id, next){
User.findById(id, function (err, user) {
next(err, user);
});
});
app.use(passport.initialize());
app.use(passport.session());
app.use(expressSession({
secret: 'aksndklajsdjicpwoemcklnaiohdandascopkqpowdmklasmdiojqwndjkasndosiqjwdklnasaksndklajsdjicpwoemcklnaiohdandascopkqpowdmklasmdiojqwndjkasndosiqjwdklnas'
}))
app.get('/', function(req, res, next){
res.render('index', {title: 'MySite'})
});
app.get('/main', function(req, res, next){
res.render('main')
});
app.get('/login', function(req, res, next){
res.render('login')
});
app.post('/signup', function(req, res, next){
User.findOne({
key: req.body.key
}, function (err, user) {
if (err) return next(err)
if (user) return next({message: 'This client exists'})
let newUser = new User({
key: req.body.key
});
newUser.save(function(err) {
if (err) return next(err);
res.redirect('/main');
});
console.log(req.body)
});
});
app.post('/login', async (req, res, next) => {
const key = req.body.key;
//const ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
//console.log(ip);
if (!key) return res.status(401).json({ err: 'Key not provided' });
const User = mongoose.model('User');
const user = await User.findOne({ key }).exec();
if (!user) return res.status(401).json({ err: 'Invalid Key' });
res.redirect('/main');
});
// 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;
Try do add this middleware to protected route:
function isAuthenticated(req,res,next){
if(req.isAuthenticated()){ // will return true if user is logged in
next();
} else{
res.redirect("/login");
}
}
app.get('/protectedPath',isAuthenticated, function(req,res) {
//protected content
);

Username entries all come out as 'null' in mongodb nodejs

I'm getting started in node.js and trying to create a user authentication system for my web application. I am watching a tutorial on YouTube and have followed every step through. When it comes to actually registering my user. the username entry in the collecting comes out as null. I'm not sure why this is happening, and I'm a rookie to javascript and node js. I am using passport, express and mongodb modules.
this is the video i am watching 'https://www.youtube.com/watch?v=m2ZzRZemc98'
If anyone knows how to fix my issue, please respond
Thanks
This is my main app.js
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");
const MongoClient = require("mongodb").MongoClient;
const passport = require("passport");
const Strategy = require("passport-local").Strategy;
const session = require("express-session");
const flash = require("connect-flash");
const authUtils = require("./utils/auth");
const hbs = require("hbs");
var indexRouter = require("./routes/index");
var usersRouter = require("./routes/users");
const authRouter = require("./routes/auth");
var app = express();
//Connet to MongoDB database
MongoClient.connect("mongodb://localhost", (err, client) => {
if (err) {
throw err;
}
const db = client.db("user-profiles");
const users = db.collection("users");
app.locals.users = users;
});
//Passport streategy
passport.use(
new Strategy((username, passport, done) => {
app.locals.users.findOne({ username }, (err, user) => {
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}
if (user.password != authUtils.hashPassword(password)) {
return done(null, false);
}
return done(null, user);
});
})
);
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser((id, done) => {
done(null, { id });
});
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "hbs");
hbs.registerPartials(path.join(__dirname, "views/partials"));
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(
session({
secret: "session secret",
resave: false,
saveUninitialized: false
})
);
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use((req, res, next) => {
res.locals.loggedIn = req.isAuthenticated();
next();
});
app.use("/", indexRouter);
app.use("/users", usersRouter);
app.use("/auth", authRouter);
// 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;
This is my auth.js
const router = express.Router();
const authUtils = require("../utils/auth");
const passport = require("passport");
router.get("/login", (req, res, next) => {
const messages = req.flash();
res.render("login", { messages });
});
router.post(
"/login",
passport.authenticate("local", {
failureRedirect: "/auth/login",
failureFlash: "Wrong username or password"
}),
(req, res, next) => {
res.redirect("/users");
}
);
router.get("/register", (req, res, next) => {
const messages = req.flash();
res.render("register", { messages });
});
router.post("/register", (req, res, next) => {
const registrationParams = req.body;
const users = req.app.locals.users;
const payload = {
username: registrationParams.username,
password: authUtils.hashPassword(registrationParams.password)
};
users.insertOne(payload, err => {
if (err) {
req.flash("error", "User account already exists");
} else {
req.flash("success", "User account was registered succesfully");
}
res.redirect("/auth/register");
});
});
router.get("/logout", (req, res, next) => {
req.session.destroy();
res.redirect("/");
});
module.exports = router;
I fixed my error, it was a mistake i made in the handlebars file, i put the input name as none the class of form-control and then named it again. Obviously the js looked at the first name and not the second name

Passport.js / Express.js Connection Refused

When I have all of my code in app.js, authenticating with Google works fine, but I tried breaking out the authentication routes in their own files and now I get a connection refused.
//authRouter.js
const express = require("express");
const authRouter = express.Router();
const SECRETS = require("../config/secrets");
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy;
const passport = require("passport");
passport.use(new GoogleStrategy(SECRETS.google,
(accessToken, refreshToken, profile, done) => {
return done(null, profile);
})
);
authRouter.get("/google", passport.authenticate('google', { scope: ['openid email profile'] }));
authRouter.get("/google/callback",
passport.authenticate("google",
{
failureRedirect: "/login",
successRedirect: "/"
},
(req, res) => {
res.render("hello world"); //successful auth, redirect home, but res is undefined
})
)
module.exports = authRouter;
//app.js
var authConfig = require('./config/secrets'),
express = require('express'),
passport = require('passport'),
TwitterStrategy = require("passport-google-oauth").OAuth2Strategy,
SECRETS = require("./config/secrets"),
authRoutes = require("./routes/authRoutes");
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((obj, done) => {
done(null, obj);
});
//setup for previously working Google auth
// passport.use(new GoogleStrategy(
// authConfig.google,
// (accessToken, refreshToken, profile, done) => {
// return done(null, profile);
// }
// ));
var app = express();
app.set('view engine', 'hbs');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
app.use(logger('dev'));
app.use(cookieParser());
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname + '/public'));
// Application routes
app.get('/', (req, res) => {
res.render('index', {
user: req.user
});
});
app.get('/login', (req, res) => {
res.render('login', {
user: req.user
});
});
//previously working google auth
// app.get('/auth/google',
// passport.authenticate('google', { scope: ['openid email profile'] }));
// app.get('/auth/google/callback',
// passport.authenticate('google', {
// failureRedirect: '/login'
// }),
// (req, res) => {
// // Authenticated successfully
// res.redirect('/');
// });
//**registering authentication routes
app.use("/auth", authRoutes);
app.get('/account', ensureAuthenticated, (req, res) => {
res.render('account', {
user: req.user
});
});
app.get('/logout', (req, res) => {
req.logout();
res.redirect('/');
});
app.listen(process.env.PORT || 3000, () => {
console.log("Listening...");
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
}
When I visit the app in a browser where I am logged i to Google, I get a connection refused. I know the credentials are correct, and it's likely some express setup I'm missing. Any thoughts? Thanks in advance.

ExpressJS backend Server with Angular2 CLI

I am using this Express Server to authenticate users by signing in by their steam account.
everything works now as expected.
What i want to know now, is how i can integrate this to my Angular2 Project, so i can use in the HomeComponent a Login Button which calls the Express Server.
Is it better to work with an Server.js or with a Server.ts Backend Server?
and will it be visible ? if yes, where should be its destination to garantuee security ?
Im new to this, thats why im so curious :)
thanks in advance
const express = require('express');
const session = require('express-session');
const FirebaseStore = require('connect-session-firebase')(session);
const firebase = require('firebase-admin');
const firebaseinit = firebase.initializeApp({
credential: ('**************************************'),
databaseURL: '**************************************'
});
// *************************************************************************************************************
var passport = require('passport'),
util = require('util'),
SteamStrategy = require('./').Strategy;
// *************************************************************************************************************
passport.serializeUser(function(user, done) {
done(null, user);
});
// *************************************************************************************************************
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
// *************************************************************************************************************
passport.use(new SteamStrategy({
returnURL: 'http://localhost:3000/auth/steam/return',
realm: 'http://localhost:3000/',
apiKey: '**************************************'
},
function(identifier, profile, done) {
process.nextTick(function () {
profile.identifier = identifier;
return done(null, profile);
});
}
));
// *************************************************************************************************************
var app = express();
app.set('views', __dirname + '/signon/views');
app.set('view engine', 'ejs');
app.use(session({
store: new FirebaseStore({
database: firebaseinit.database()
}),
secret: 'keyboard cat',
name: 'name of session id',
resave: true,
saveUninitialized: true
}));
// *************************************************************************************************************
// *************************************************************************************************************
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname + '/../../public'));
// app.post('/auth/openid', passport.authenticate('openid'));
// *************************************************************************************************************
app.get('/auth/steam',
passport.authenticate('steam', { failureRedirect: '/' }),
function(req, res) {
res.redirect('/');
});
// *************************************************************************************************************
app.get('/auth/steam/return',
passport.authenticate('steam', { failureRedirect: '/' }),
function(req, res) {
res.redirect('/');
var db = firebase.database();
var ref = db.ref("/UserID");
var SteamUserID = ref.child(req.user.id);
SteamUserID.update({
Username : req.user.displayName,
UserImg : req.user.photos[2].value
});
});
// *************************************************************************************************************
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
// *************************************************************************************************************
app.get('/', function(req, res){
res.render('index', { user: req.user });
});
// *************************************************************************************************************
app.get('/account', ensureAuthenticated, function(req, res){
res.render('account', { user: req.user });
});
// *************************************************************************************************************
app.listen(3000, function () {
console.log('listening on port 3000!')
})
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/');
}
console.log('Listening on port ' + app.listen);

Categories

Resources