Authentication on NodeJS - node.js

I've watched a video on YouTube about Authentication on NodeJS. I already have a project just with get requisitions. That's the code that involves the login:
var sessions = require('express-session');
var session = {};
app.use(bodyParser.urlencoded({ extended: true }));
app.use(sessions({
secret: 'aisdh2782782hjda82',
resave: false,
saveUninitialized: true
}))
Methods
app.get('/login', function(req, res) {
session = req.session;
if(session.uniqueId) {
resp.redirect('/redirects');
}
})
app.post('/login', function(req,res) {
session = req.session;
if(req.body.username == 'admin' && req.body.password == 'admin'){
session.uniqueiD = req.body.username;
}
resp.redirect('/redirects');
});
app.post('/logout', function(req,res) {
req.session.destroy();
});
app.get('/redirects', function(req, res) {
session = req.session;
if(session.uniqueiD) {
resp.redirect('/home');
} else {
end('Wrong. Try it again');
}
});
Tests
I'm testing the source with postman. For instance I've tried using post login method passing as parameter this JSON:
{
"username": "admin",
"password": "admin"
}
Then I got this:
resp is not defined
May someone help me? I have limited knowledge of node and I don't really know what's wrong in my code (I just copied). Obs: I'll use mysql to fetch user data.

I haven't yet implemented your code myself, but it comes to my eye that you pass in the parameters (req, res) and refer to the later with "resp" instead of "res". It might just be a simple typo.
Also you don't handle a correct login diffrent from an incorrect one. Implement an "else {}" case after you ceck for successful login.

Related

req.user undefined despite successful signup with Passport and Express Session on NodeJS

The Problem
I am setting up my NodeJS & Express App, using Passport for authentication with Google Sign In and Facebook Login. Everything works very well when working on localhost, but when I deploy my app (to Vercel) I can't make the sessions work.
The signin process works very well, and I can see the user information attached to req.session, and req.user contains all user information.
However, right after that, when calling any route, req.user is undefined
The code
//Setting up the app
const express = require('express');
//const https = require('https');
//Bodyparser to handle JSON
const bodyParser = require('body-parser');
//Mongoose to connect to MongoDB
const mongoose = require('mongoose');
//To handle environments
const keys = require('./keys')
//To handle user sessions
var session = require("express-session");
var MongoDBStore = require('connect-mongodb-session')(session);
//Passport to hangle Google Sign In
var passport = require('passport');
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
//Authentication: serialize and deserialize user
passport.serializeUser(function(user, done) {
console.log(`serialize: user:${user}`);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
console.log(`deserialize user:${user}`)
done(err, user);
});
});
//Authentication: Google Sign In
passport.use(new GoogleStrategy({
clientID: keys.GOOGLE_CLIENTID,
clientSecret: keys.GOOGLE_SECRET,
callbackURL: keys.URL_GOOGLE_CALLBACK
},
function callback(accessToken, refreshToken, profile, done) {
process.nextTick( ()=> {
User.findOne({'googleId': profile.id}, (err,user)=> {
if(err)
return done(err,false);
if(user){
return done(null, user);
}
else{
var newUser = new User();
newUser.googleId = profile.id;
newUser.googleToken = accessToken;
newUser.firstName = profile.name.givenName;
newUser.email = profile.emails[0].value;
newUser.authType = "Google";
newUser.image = profile.photos[0].value;
newUser.save((err)=> {
if(err)
throw err;
return done(null, newUser);
});
}
});
});
}
));
//Importing the models used
const Country = require('./models/country');
const Place = require('./models/place');
const User = require('./models/user');
const Trip = require('./models/trip');
//Starting the app
const app = express();
//Using body parser as global middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }))
//Using cookie bodyParser
app.use(require('cookie-parser')('keyboard cat'))
//Using Cors for routes
//app.use(cors())
//Store for sessions
var storeSessions = new MongoDBStore({
uri: keys.URI_MONGO,
collection: 'sessions'
});
// Catch errors
storeSessions.on('error', function(error) {
console.log(error);
});
//Added but not sure if useful
app.use(cors({credentials: true, origin: true}));
app.set('trust proxy', 1);
//Setting up a session
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: false,
proxy: true,
store: storeSessions,
cookie : {
maxAge: 2419200000
}
}));
//Using passport for authentication
app.use(passport.initialize());
app.use(passport.session());
//Solving CORS issues
app.use((req, res, next) => {
let allowedOrigins = ['http://localhost:3000', 'http://localhost:8080', 'mywebsite.com'];
let origin = req.headers.origin;
if(allowedOrigins.indexOf(origin) > -1){
res.setHeader('Access-Control-Allow-Origin', origin);
}
//res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content, Accept, Content-Type, Authorization');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
res.header('Access-Control-Allow-Credentials', true);
next();
});
//Connection to MongoDB
mongoose.connect(keys.URI_MONGO, {useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('Connection successful!'))
.catch((error) => { console.error(error); });
//The API call from the Google sign in button
app.get('/authgoogle',
passport.authenticate('google', { scope : ['profile', 'email'] }));
//Callback from Google Sign in
app.get('/authgoogleredirect', function(req, res, next) {
passport.authenticate('google', {
scope : ['profile', 'email']
}, function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect(keys.URL_SIGN_IN); }
req.logIn(user, function(err) {
if (err) { return next(err); }
req.session.user = req.user;
req.session.save(function(){
console.log(`req.session.user in callback: ${req.session.user}`)
console.log(`req.session in callback: ${JSON.stringify(req.session)}`)
res.redirect(keys.URL_LOGGED_IN);
});
});
})(req, res, next);
});
//Middleware to check if user is logged in
function isLoggedIn(req, res, next) {
console.log(`req.session in isloggedin: ${JSON.stringify(req.session)}`);
console.log(`req.user in isloggedin: ${JSON.stringify(req.user)}`);
if (req.isAuthenticated()) {
next();
} else {
data = {
"redirect": true,
"url": keys.URL_SIGN_IN
}
res.send(JSON.stringify(data));
}
}
//--------------------USERS------------------------
//Getting the currently logged in user
app.get('/getcurrentuser', isLoggedIn, function(req, res, next) {
res.send(req.user);
});
What works and what does not
The google sign in works well, and passport.serialize and passport.deserialize work well, I can see the user object.
When I try to reach GET /getcurrentuser (call on all pages), I don't get the req.user object and isAuthenticated() always returns false.
These are the logs of the middleware isloggedin :
req.session in isloggedin: {"cookie":{"originalMaxAge":2419200000,"expires":"2020-08-07T12:09:54.220Z","httpOnly":true,"path":"/"}}
req.user in isloggedin: undefined
The sessions are correctly saved in the session collection in mongoDB.
Serialize and deserialize don't seem to be called after sign in, not sure if that's normal.
What I tried
I read plenty of answers to similar problems but none seem to work:
order of initialization of passport and express session: it should be correct
proxy: added but did not change anything
credentials: include has always been included in my front end fetch call
cookie.secure: false: turned it on and off, without success
cookie session tried to use it instead of express session, without success
It must be something stupid but I can't seem to find it...
What troubles me is why would this work on localhost?
Thanks a lot for your time :)
Alright, if anyone comes across this exact issue, I finally solved it:
req.user always came as undefined, because my front end and back end have different domain names (I'm using the free heroku tier) therefore the cookie was considered third-party, blocked by Google Chrome and never sent to my express app!
As soon as I disabled third-party cookie blocking in Chrome settings the session became persistent!
The passport and session configurations were correct all along...
Thanks #abhinav for your help and time :)
Passport has its own session handling code embedded in its library, if you want to store your passport login user to session-database you can do
router.get("/redirect", passport.authenticate('google',{failureRedirect:'/fail',successRedirect:'/success'}, (req,res)=>{
req.session.user = req.user;
});
and keeping your remaining code same as you have done, this will save your session in the database

Passport js serializeUser & deserializeUser

I have read everything on the argument but still cannot understand it. The documentation on the Passport Js web site is very vague.
I am using Passport JS with the passport-ldapauth Strategy. I do not have a Database. I obviously don't want to hit the LDAP server on each request. I would like to authenticate the user the first time on the POST /login route using the passport strategy with LDAP, store the user in the session and on each subsequent requests I just want to check if the user is already logged in.
I am trying to use the session but I cannot understand how to use Passport + session with the serialize/deserialize flow. Every example I checked use a User.findOne in the deserializeUser function.
As of now I disabled the use of the session for Passport and I am using a custom middleware where I check if req.session.user != null. If that's the case the user is already logged in and I hit next(). Otherwise redirect to login.
Here is some code (for sake of simplicity I deleted the code not related to the question):
Passport configuration:
var express = require('express'),
session = require('express-session'),
passport = require('passport'),
LdapStrategy = require('passport-ldapauth');
var app = express();
var LdapStrategyOptions = {
server: {
url: '<url>',
bindDN: '<dn>',
bindCredentials: "<pwd>",
searchBase: '<searchBase>',
searchFilter: '<filter>'
}
};
passport.use(new LdapStrategy(LdapStrategyOptions));
app.use(cookieParser());
app.use(session({
store: new LokiStore({autosave: false}),
resave: false,
saveUninitialized: false
secret: env.get("SESSION_SECRET")
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(passport.initialize());
Routes:
// LOGIN ROUTE
app.get('/login',
function(req, res) {
res.render('login');
});
// LOGIN HANDLER ROUTE
app.post('/login',
passport.authenticate('ldapauth', { session: false }),
function(req, res) {
req.session.userId = req.user.cn;
req.session.user = {
"userId": req.user.cn,
"displayName": req.user.displayName
};
res.redirect('/');
});
// LOGOUT ROUTE
app.get('/logout',
function(req, res) {
req.session.destroy(function(err) {
req.logout();
res.redirect('/');
});
});
// HOME ROUTE
app.get('/', isLoggedIn, function(req, res) {
res.render('home');
});
IsLoggedIn Middleware:
var isLoggedIn = function(req, res, next) {
if (req.session.user != null){
console.log("is auth ok '" + req.session.user.userId +"'");
return next();
}
console.log("redirect to auth/login");
res.redirect('/auth/login');
}
What am I missing? Is there any security fault in my setup?
Any help is appreciated.
From passportjs docs:
In a typical web application, the credentials used to authenticate a user will only be transmitted during the login request. If authentication succeeds, a session will be established and maintained via a cookie set in the user's browser.
Each subsequent request will not contain credentials, but rather the unique cookie that identifies the session. In order to support login sessions, Passport will serialize and deserialize user instances to and from the session.
Basically serializeUser is supposed to return a unique user identifier so you can deserializeUser back into JSON later.
So for your implementation you should probably do something along these lines:
DISCLAIMER: I have no experience with LDAP.
passport.serializeUser(function(user, done) {
//We can identify the user uniquely by the CN,
//so we only serialize this into the session token.
done(null, user.cn);
});
passport.deserializeUser(function(cn, done) {
//Directly query LDAP.
//I'm not sure passport caches the result (only calls deserializeUser for new sessions)
//but worst case you can cache the result yourself.
somehowLoadUserFromLDAPByCN(cn, function(err, user) {
done(err, {
userId: user.cn,
displayName: user.displayName
});
});
});
If you only need an id and a display name, it's totally fine to keep them in session. You should only load the full user profile when you need more fields.

mynodejs login page is not responding

I'm new to node js and i tried creating a simple login page. but when i run my code it takes me to the login page alright. the problem is when i enter a user name and password, it doesn't display the information it supposed to display.
var express = require('express');
var sessions = require('express-session');
var session;
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(sessions({
secret: '2937#&&#',
resave: false,
saveUninitialized: true
}))
app.get('/login', function(req, resp){
session = req.session;
if(session.uniqueID){
resp.redirect('/redirects');
}
resp.sendFile('./files/login.html', {root: __dirname});
});
app.post('/login', function(req, resp){
// resp.end(JSON.stringify(req.body));
session = req.session;
if(session.uniqueID) {
resp.redirect('/redirects');
}
if(req.body.username == 'admin' && req.body.password == 'admin'){
session.uniqueID = req.body.username;
}
resp.redirect('/redirects');
});
app.get('/logout', function(req, resp){
req.session.destroy();
resp.redirect('/login');
});
app.get('/admin', function(req, resp){
session = req.session;
if(session.uniqueID != 'admin'){
resp.end('Unauthorised acess')
}
resp.end('You are good');
})
app.get('/redirects', function(req, resp){
session = req.session;
if(session.uniqueID =='admin') {
console.log(session.uniqueID)
resp.redirect('/admin');
} else {
resp.send(req.session.uniqueID + 'not found KILL SESSION');
}
})
app.listen(1337, function() {
console.log('Listening at port 1337');
});
Nothing happens because you can't redirect on an AJAX call. Your POST probably works, but then your redirect directive has no effect.
Try sending a "success" response if the username and password are good (a simple res.send('OK'); would do) and then on the client side redirect the user to /redirects (window.location.replace('https://yoursite.com/redirects')); if a success code is returned.
This will be handled by your GET route for /redirects and you should see what you want.

Isomorphic react App can't find req.login after logging in

I log in with the user at the login, and the user object gets saved for req.user (or passports user) however after I go to a different route/state it doesnt hold the user object there anymore. To demonstrate I just try to console.log(req.user) and it returns undefined, for a POST method (updateUserProfile) in my controller. I used PostMan to test the POST method, the GET method worked on Postman for grabbing all users. If I refresh the page the app.get(*) will load the req.user and print it fine, its just in the calls. What could be the reason? Could it be my express setup? Example:
My routes:
/**
* Routes for express app
*/
var express = require('express');
var users = require('../controllers/users');
var feedback = require("../controllers/feedbackapi");
var problem = require("../controllers/problemapi");
var pair = require("../controllers/userproblempairapi");
var mongoose = require('mongoose');
var _ = require('lodash');
var Header = require('../../public/assets/header.server');
var App = require('../../public/assets/app.server');
module.exports = function(app, passport) {
// user routes
app.post('/login', users.postLogin);
app.post('/signup', users.postSignUp);
app.get('/logout', users.getLogout);
app.post('/updateUserProfile', users.updateUserProfile);
// google auth
// Redirect the user to Google for authentication. When complete, Google
// will redirect the user back to the application at
// /auth/google/return
// Authentication with google requires an additional scope param, for more info go
// here https://developers.google.com/identity/protocols/OpenIDConnect#scope-param
app.get('/auth/google', passport.authenticate('google', { scope: [
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email'
] }));
// Google will redirect the user to this URL after authentication. Finish the
// process by verifying the assertion. If valid, the user will be logged in.
// Otherwise, the authentication has failed.
app.get('/auth/google/callback',
passport.authenticate('google', {
successRedirect: '/',
failureRedirect: '/login'
}));
//Important** on refresh we look at our wildcard call to find out if we're still logged in.
// Retrieves all topics on any endpoint for demonstration purposes
// If you were indeed doing this in production, you should instead only
// query the Topics on a page that has topics
app.get('*', function(req, res, next) {
// We don't want to be seeding and generating markup with user information
var user = req.user ? { authenticated: true, isWaiting: false } : { authenticated: false, isWaiting: false };
// An object that contains response local variables scoped to the request, and therefore available only to the view(s) rendered during
// that request/response cycle (if any). Otherwise, this property is identical to app.locals
// This property is useful for exposing request-level information such as request path name, authenticated user, user settings, and so on.
// pass in data to be seeded into the TopicStore
res.locals.data = {
UserStore: { user: user }
};
next();
});
// This is where the magic happens. We take the locals data we have already
// fetched and seed our stores with data.
// App is a function that requires store data and url to initialize and return the React-rendered html string
app.get('*', function (req, res, next) {
var html = App(JSON.stringify(res.locals.data || {}), req, res);
html = html.replace("TITLE", Header.title)
.replace("META", Header.meta);
if(process.env.NODE_ENV === 'devhotloader') {
html = html.replace("LINK", '');
} else {
html = html.replace("LINK", Header.link);
}
res.contentType = "text/html; charset=utf8";
res.end(html);
});
};;
My users controller:
var _ = require('lodash');
var User = require('../models/user');
var passport = require('passport');
var ParsonsProblem = require('../models/parsonsproblem');
var Feedback = require('../models/feedback');
var UserProblemPair = require('../models/userproblempair');
/**
* POST /login
*/
exports.postLogin = function(req, res, next) {
// Do email and password validation for the server
/*var Feed = new Feedback({
description: 'Supsuop'
});
var Problem = new ParsonsProblem({
description: 'Test',
feedback: Feed
});
var Pair = new UserProblemPair({
problem_id: Problem,
attempt_quantity: 0,
completed: true
});
*/
console.log(req.body);
passport.authenticate('local', function(err, user, info) {
if(err) return next(err);
if(!user) {
req.flash('errors', {msg: info.message});
}
// Passport exposes a login() function on req (also aliased as logIn()) that can be used to establish a login session
req.logIn(user, function(err) {
if(err) return next(err);
req.flash('success', { msg: 'Success! You are logged in'});
res.end('Success');
console.log(req.user);
});
})(req, res, next);
/*
Feed.save(function(err) {console.log('Feedback saved');});
Problem.save(function(err) {console.log('Problem saved');});
Pair.save(function(err) {console.log('ProblemPair saved');});
console.log(Feed);
*/
};
/**
* POST UpdateUser Profile
*/
exports.updateUserProfile = function(req, res) {
var id = req.user._id;
if (req.body.firstName == "") {
req.body.firstName = req.user.profile.firstName;
}
if (req.body.lastName == "") {
req.body.lastName = req.user.profile.lastName;
}
if (req.body.gender == "") {
req.body.gender = req.user.profile.gender;
}
if (req.body.section == "") {
req.body.section = req.user.profile.section;
}
User.findById(id, function(err, user) {
console.log("ID: " + id);
user.profile.firstName = req.body.firstName;
user.profile.lastName = req.body.lastName;
user.profile.gender = req.body.gender;
user.profile.section = req.body.section;
user.save();
res.end();
});
}
/**
* GET /logout
*/
exports.getLogout = function(req, res, next) {
// Do email and password validation for the server
console.log("User has been logged out");
req.logout();
res.redirect('/');
//res.end():
};
/**
* POST /signup
* Create a new local account
*/
exports.postSignUp = function(req, res, next) {
var user = new User({
email: req.body.email,
password: req.body.password,
profile: {
firstName : req.body.firstName,
lastName : req.body.lastName,
section : req.body.section
}
});
//user.profile.firstName = req.body.firstName;
//user.profile.lastName = req.body.lastName;
//user.profile.section = req.body.section;
User.findOne({email: req.body.email}, function(err, existingUser) {
if(existingUser) {
req.flash('errors', { msg: 'Account with that email address already exists' });
res.redirect('/sign');
}
user.save(function(err) {
if(err) return next(err);
req.logIn(user, function(err) {
if(err) return next(err);
console.log('Successfully created');
console.log('Printing user');
console.log(user);
console.log('Print our body from our request');
console.log(req.body);
res.redirect('/');
});
});
});
};
Express Setup:
app.disable('x-powered-by');
app.set('views', path.join(__dirname, '..', 'views'));
app.set('view cache', false);
app.use(bodyParser.json({limit: '100mb'}));
app.use(bodyParser.urlencoded({extended: true})); // for parsing application/x-www-form-urlencoded
app.use(methodOverride());
app.use(express.static(path.join(__dirname, '../..', 'public')));
// I am adding this here so that the Heroku deploy will work
// Indicates the app is behind a front-facing proxy,
// and to use the X-Forwarded-* headers to determine the connection and the IP address of the client.
// NOTE: X-Forwarded-* headers are easily spoofed and the detected IP addresses are unreliable.
// trust proxy is disabled by default.
// When enabled, Express attempts to determine the IP address of the client connected through the front-facing proxy, or series of proxies.
// The req.ips property, then, contains an array of IP addresses the client is connected through.
// To enable it, use the values described in the trust proxy options table.
// The trust proxy setting is implemented using the proxy-addr package. For more information, see its documentation.
app.enable('trust proxy');
// Cookie parser should be above session
// cookieParser - Parse Cookie header and populate req.cookies with an object keyed by cookie names
// Optionally you may enable signed cookie support by passing a secret string, which assigns req.secret
// so it may be used by other middleware
app.use(cookieParser());
// Create a session middleware with the given options
// Note session data is not saved in the cookie itself, just the session ID. Session data is stored server-side.
// Options: resave: forces the session to be saved back to the session store, even if the session was never
// modified during the request. Depending on your store this may be necessary, but it can also
// create race conditions where a client has two parallel requests to your server and changes made
// to the session in one request may get overwritten when the other request ends, even if it made no
// changes(this behavior also depends on what store you're using).
// saveUnitialized: Forces a session that is uninitialized to be saved to the store. A session is uninitialized when
// it is new but not modified. Choosing false is useful for implementing login sessions, reducing server storage
// usage, or complying with laws that require permission before setting a cookie. Choosing false will also help with
// race conditions where a client makes multiple parallel requests without a session
// secret: This is the secret used to sign the session ID cookie.
// name: The name of the session ID cookie to set in the response (and read from in the request).
// cookie: Please note that secure: true is a recommended option.
// However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies.
// If secure is set, and you access your site over HTTP, the cookie will not be set.
var sess = {
resave: true,
saveUninitialized: true,
// Use generic cookie name for security purposes
key: 'sessionId',
secret: secrets.sessionSecret,
// Add HTTPOnly, Secure attributes on Session Cookie
// If secure is set, and you access your site over HTTP, the cookie will not be set
cookie: {
expires: false,
httpOnly: false,
//secure: false
},
store: new MongoStore({ url: secrets.db, autoReconnect: true})
};
var node_env = process.env.NODE_ENV;
console.log('Environment: ' + node_env);
//if(node_env === 'production') {
//sess.cookie.secure = false; // Serve secure cookies
//}
app.use(session(sess));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
edit: Printing out the req.session and req.user only display when logging in and signing in/out, when transitioning to another view with react-router it doesn't have that info anymore. ("tried with console logs")
I think you have to user react-router to handle internal redirects.

Passport.js: how to access user object after authentication?

I'm using Passport.js to login a user with username and password. I'm essentially using the sample code from the Passport site. Here are the relevant parts (I think) of my code:
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
passport.use(new LocalStrategy(function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login/fail', failureFlash: false }),
function(req, res) {
// Successful login
//console.log("Login successful.");
// I CAN ACCESS req.user here
});
This seems to login correctly. However, I would like to be able to access the login user's information in other parts of the code, such as:
app.get('/test', function(req, res){
// How can I get the user's login info here?
console.log(req.user); // <------ this outputs undefined
});
I have checked other questions on SO, but I'm not sure what I'm doing wrong here. Thank you!
Late to the party but found this unanswered after googling the answer myself.
Inside the request will be a req.user object that you can work withr.
Routes like so:
app.get('/api/portfolio', passport.authenticate('jwt', { session: false }), stocks.buy);
Controller like this:
buy: function(req, res) {
console.log(req.body);
//res.json({lel: req.user._id});
res.json({lel: req.user});
}
In reference to the Passport documentation, the user object is contained in req.user. See below.
app.post('/login',
passport.authenticate('local'),function(req, res) {
// If this function gets called, authentication was successful.
// `req.user` contains the authenticated user.
res.redirect('/users/' + req.user.username);
});
That way, you can access your user object from the page you redirect to.
In case you get stuck, you can refer to my Github project where I implemented it clearly.
I'm pretty new to javascript but as I understand it from the tutorials you have to implement some session middleware first as indicated by 250R.
const session = require('express-session')
const app = express()
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
let sess = {
genid: (req) => {
console.log('Inside the session middleware')
console.log(req.sessionID)
return uuid()
},
store: new FileStore(),
secret: 'keyboard cat', // password from environment
resave: false,
rolling: true,
saveUninitialized: true,
cookie: {
HttpOnly: true,
maxAge: 30 * 60 * 1000 // 30 minutes
}
}
app.use(session(sess))
// call passport after configuring the session with express-session
// as it rides on top of it
app.use(passport.initialize())
app.use(passport.session())
// then you will be able to use the 'user' property on the `req` object
// containing all your session details
app.get('/test', function (req, res) {
console.log(req.user)
})
res.render accepts an optional parameter that is an object containing local variables for the view.
If you use passport and already authenticated the user then req.user contains the authenticated user.
// app.js
app.get('/dashboard', (req, res) => {
res.render('./dashboard', { user: req.user })
})
// index.ejs
<%= user.name %>
You can define your route this way as follows.
router.post('/login',
passport.authenticate('local' , {failureRedirect:'/login', failureFlash: true}),
function(req, res) {
res.redirect('/home?' + req.user.username);
});
In the above code snippet, you can access and pass any field of the user object as "req.user.field_name" to the page you want to redirect. One thing to note here is that the base url of the page you want to redirect to should be followed by a question mark.
late to party but this worked for me
use this in your app.js
app.use(function(req,res,next){
res.locals.currentUser = req.user;
next();
})
get current user details in client side like ejs
<%= locals.currentUser.[parameter like name || email] %>
Solution for those using Next.js:
Oddly, —> the solution <— comes from a recently removed part of the README of next-connect, but works just as it should. You can ignore the typescript parts if you're using plain JS.
The key part is the getServerSideProps function in ./src/pages/index (or whichever file you want to get the user object for).
// —> ./src/authMiddleware.ts
// You'll need your session, initialised passport and passport with the session,
// so here's an example of how we've got ours setup, yours may be different
//
// Create the Passport middleware for SAML auth.
//
export const ppinit = passport.initialize();
//
// Set up Passport to work with expressjs sessions.
//
export const ppsession = passport.session();
//
// Set up expressjs session handling middleware
//
export const sess = session({
secret: process.env.sessionSecret as string,
resave: true,
saveUninitialized: true,
store: sessionStore,
});
// —> ./src/pages/index.ts
// update your user interface to match yours
export interface User {
id: string;
name: string;
}
interface ExtendedReq extends NextApiRequest {
user: User;
}
interface ServerProps {
req: ExtendedReq;
res: NextApiResponse;
}
interface ServerPropsReturn {
user?: User;
}
export async function getServerSideProps({ req, res }: ServerProps) {
const middleware = nc()
.use(sess, ppinit, ppsession)
.get((req: Express.Request, res: NextApiResponse, next) => {
next();
});
try {
await middleware.run(req, res);
} catch (e) {
// handle the error
}
const props: ServerPropsReturn = {};
if (req.user) props.user = req.user;
return { props };
}
interface Props {
user?: User;
}
//
// A trivial Home page - it should show minimal info if the user is not authenticated.
//
export default function Home({ user }: Props) {
return (
<>
<Head>
<title>My app</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1>Welcome to My App {user?.name}</h1>
</main>
</>
);
}
You'll need to make sure that you register a middleware that populates req.session before registering the passport middlewares.
For example the following uses express cookieSession middleware
app.configure(function() {
// some code ...
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.cookieSession()); // Express cookie session middleware
app.use(passport.initialize()); // passport initialize middleware
app.use(passport.session()); // passport session middleware
// more code ...
});

Resources