I'm at a complete loss with this. I can only assume it's passport because when I comment out its initialization everything magically works again. I have 2 routes currently setup. One is a get request that requires a user to be logged in and the other is a post request that actually does the logging in.
in my app.js file my passport setup looks like this:
var sessionStore = new MySQLStore(options);
//handles cookie/session creation
app.set('trust proxy', 1) // trust first proxy
app.use(session({
secret: config.sessionKey,
resave: false,
store:sessionStore,
saveUninitialized: false,
cookie: {
//secure: true,
maxAge:24*60*60*1000 //1 day in milliseconds
}
}));
app.use(passport.initialize());
app.use(passport.session());
require('./services/passport');
//initiate route handlers
app.use('/login', require('./routes/authRoutes'));
app.use('/tiles', require('./routes/tileRoutes'));
I am using a local strategy as my users won't be using any kind of social app to login. I configured another file passport.js to actually handle the passport setup. I am using the sequelize database in order to verify users. This whole process looks like this:
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
passport.serializeUser((user, done)=>{
done(null, user.id);
});
passport.deserializeUser((user, done)=>{
done(null, user.id);
});
passport.use(new LocalStrategy(function (username, password, done) {
const db = require('../models');
db.user.findOne({ where: {username: username} })
.then((user)=>{
if(!user){
return done(null, false);
}else{
// if(user.dataValues.hashed_password === password)
// return done(null, user);
bcrypt.compare(password, user.dataValues.hashed_password, function(err, res) {
if(res === true){
return done(null, user);
}else{
return done(null, err);
}
});
}
});
}));
signing people up, creating the session, and storing the session id all seem to be happening, however when I start making get/post requests on my front end with axios (I'm using react) I continually get a internal server error. I've tried catching this in everyway I can think of, breaking at definite points, an console.logging out but I just get the same message:
[0] GET /tiles 500 8.049 ms - 2
[0] GET /tiles 500 2.757 ms - 2
or from the console
GET http://localhost:3000/tiles/ 500 (Internal Server Error)
the actual get request looks like this (i havent' put much in till I know it works):
const express = require('express');
const router = express.Router();
router.get('/', isLoggedIn, (req, res)=>{
debugger;
res.send({hi:'there'})
});
function isLoggedIn(req, res, next) {
debugger;
if (req.isAuthenticated()) return next();
console.log('failure');
res.redirect('/login')
}
module.exports=router;
The deserializeUser should call the function to find user by id here, then pass it to done, the first param is userId as serializeUser return the user.id to session store. Example:
passport.deserializeUser((id, done)=>{
passport.deserializeUser((id, done) => {
User.findById(id).then((user) => {
done(null, user);
}).catch(done);
});
});
Related
I am trying to display a page to the user(front-end), which shows them their login history but am a bit confused and need some help please.
Am using Express, and storing my sessions in mongoStore like this:
app.use(session({
secret: process.env.SECRET,
key: process.env.KEY,
resave: false,
saveUninitialized: false,
store: new MongoStore({
mongooseConnection: mongoose.connection
})
}));
and my login strategy is local which is located in my userController file like this:
exports.login = passport.authenticate('local', {
failureRedirect: '/login',
failureFlash: 'Failed Login!',
successRedirect: '/',
successFlash: 'You are now logged in!'
});
meanwhile I have a helpers function in my handlers like this:
const passport = require('passport');
const mongoose = require('mongoose');
const User = mongoose.model('User');
const sess = passport.use(User.createStrategy()); // creates strategy during every user login
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
I know that I have to create a token during each user login but i believe that is already creeated using the serialized function(in this case it's email) but then how can i keep track of the users so that during their next session, I can retrieve the date they last logged in and render(show) it to them? Authentication and login works perfect, i just need to know how I am going to display their previous logins any other future time they are signed in and click to a specific route (not homepage). thanks in advance
You should implement a customized authenticate handler to store the data you need when a user successful login,
Router.post('/login', (req, res, next)=>{
passport.authenticate('local', function(err, user) {
if (err) { //do something when user failed to authenticate... }
if (!user) { //do something when user not found }
//explicitly call req.logIn, then save related information you need
req.logIn(user, function(err) {
if (err) { //do something when user failed to login }
//for example, save the current time to user collection
Users.updateLastLoginTime(user.id, Date.now()).then(function(){
//when all set, send the response
return res.json(true);
})
});
})(req, res, next);
})
In addition to #MarkoCen's answer, something like this will perhaps be the method in your Users model:
// set a time for the login
UserSchema.statics.updateLastLoginTime = function(userId, currentTime, callback) {
User.findOne({ _id: userId }, 'lastLoginTime')
.exec(function(error, user){
if (error) {
return callback(error);
} else if(!userId) {
var err = new Error('User not found.');
err.status = 401;
return callback(err);
}
user.lastLoginTime = currentTime;
});
};
When im logging in the req.user is displayed as it should, but after navigating to /test , the req.user is undefined.
Why is that?
server.js
var express = require('express'); // call express
var app = express(); // define our app using express
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var session = require('express-session');
var router = express.Router();
var Account = require('src/app/models/Users.js');
var Core = require('/src/app/gamemodels/core');
// Init passport authentication
var passport = require('passport');
var Strategy = require('passport-local').Strategy;
require('/src/config/passport')(passport);
var cookieParser = require('cookie-parser')
// required for passport session
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
mongoose.connect('DB');
app.use(cookieParser()) // required before session.
app.use(session({ secret: 'xxxx' }));
app.use(passport.initialize());
app.use(passport.session());
var port = process.env.PORT || 3000; // set our port
// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(req, res) {
res.json({ text: 'hooray! welcome to our api!' });
});
router.get('/test', function(req,res) {
console.log(req);
console.log(req.user);
res.json(req.user);
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
}));
router.post('/login', passport.authenticate('local-login'), function(req, res) {
console.log("executed login!");
console.log(req.user);
req.session.user = req.user;
});
});
*/
// more routes for our API will happen here
// REGISTER OUR ROUTES -------------------------------
// all of our routes will be prefixed with /api
app.use('/api', router);
// START THE SERVER
// =============================================================================
app.listen(port);
console.log('Magic happens on port ' + port);
passport js:
// config/passport.js
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var Account = require('src/app/models/Users.js');
// expose this function to our app using module.exports
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
Account.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) { // callback with email and password from our form
console.log("doing local login");
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
Account.findOne({ 'username' : username }, function(err, user) {
var thisuser = user;
console.log("query account is done");
// if there are any errors, return the error before anything else
if (err) {
console.log("error occured");
return done(err);
}
console.log("if user exist check");
// if no user is found, return the message
if (!user)
return done(null, false,'No user found.'); // req.flash is the way to set flashdata using connect-flash
console.log("checking password");
// if the user is found but the password is wrong
if (!user.validPassword(password)) {
console.log("password is not valid");
return done(null, false, 'Oops! Wrong password.'); // create the loginMessage and save it to session as flashdata
}
console.log("all good! logging in!");
req.login(thisuser, function(error) {
if (error) return next(error);
console.log("Request Login supossedly successful.");
});
// all is well, return successful user
return done(null, thisuser);
});
}));
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
process.nextTick(function() {
console.log("doing local signup");
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
Account.findOne({ 'username' : username }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, 'That username is already taken.');
} else {
var newUser = new Account();
// set the user's local credentials
newUser.username = username;
newUser.password = newUser.encryptPassword(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
};
EDIT1:
changed passport.js serialize function and deserialize function to the following:
passport.serializeUser(function(user, done) {
done(null, user.username);
});
// used to deserialize the user
passport.deserializeUser(function(username, done) {
Account.findOne({'username': username}, function(err, user) {
done(err, user);
});
});
still did not make any difference. Undefined still occur.
EDIT2:
value of user in serializing:
{ _id: 5909a6c0c5a41d13340ecf94,
password: '$2a$10$tuca/t4HJex8Ucx878ReOesICV6oJoS3AgYc.LxQqCwKSV8I3PenC',
username: 'admin',
__v: 0,
inFamily: false,
bank: 500,
cash: 2500,
xp: 0,
rank: 1,
bullets: 0,
location: 1,
permission: 0,
health: 100 }
edit3:
changed the login func to:
router.post('/login', passport.authenticate('local-login'), function(req, res) {
console.log("executed login!");
console.log(req.user);
req.session.user = req.user;
req.logIn(req.user, function (err) {
if (err) {
return next(err);
}
});
});
server log response:
doing local login
query account is done
if user exist check
checking password
all good! logging in!
serializing!
Request Login supossedly successful.
serializing!
executed login!
{ _id: 5909a6c0c5a41d13340ecf94,
password: '$2a$10$tuca/t4HJex8Ucx878ReOesICV6oJoS3AgYc.LxQqCwKSV8I3PenC',
username: 'admin',
__v: 0,
inFamily: false,
bank: 500,
cash: 2500,
xp: 0,
rank: 1,
bullets: 0,
location: 1,
permission: 0,
health: 100 }
serializing!
still no sign to unserialize log.
The reason is that you are missing on the deserialization part.
/**
* Each subsequent request will contain a unique
* cookie that identifies the session. In order to support login sessions,
* Passport will serialize and deserialize user instances to and from the session.
*/
passport.serializeUser(function (user, done) {
done(null, user.username);
});
passport.deserializeUser(function (username, done) {
/**
* Necessary to populate the express request object with
* the 'user' key
* Requires(*):
* - session support with express
* - call to logIn from passport.auth)enticate if using authenticate
* callback.
*/
// TODO: Verify if username exists
done(null, username);
});
So after the user is authenticated or when req.isAuthenticated() is true, the deserialization middleware function will be invoked and will update the request object with username or req.user in your case.
Reference:
passport js sessions
Since you are using a custom callback to handle success or failures, it becomes the application's responsibility to establish a session by calling req.logIn. So after the user is authenticated, add
req.logIn(user, function (err) {
if (err) { return next(err); }
return { // Do a redirect perhaps? }
});
Refer to section Custom Callbacks in the reference link, I gave you.
When defining methods and middleware on the passport object, order matters. Your code is pretty entangled. A little decoupling will go a long way here.
Move all of the strategy logic out of server.js and your passport.js. Put it in its own set of files. Also, you don't need to include the base Strategy in the server file.
Define an express router in a separate file and mount the routes in your server.js
passport.initialize() and passport.session() middlewares need to attach to your express app instance before you define serialize and deserialize.
No need to set req.session.user, which defeats the purpose of storing just the user id in the session. On each request to express, once you deserialize the user by reading the id in req.session.passport.user, you're loading the entire user account document into req.user and you can access all user data directly from req.user.
If you're using a pre-packaged passport Strategy constructor which calls done(), you don't need to call req.login anywhere.
server.js
//express, body parser, express session, etc
const app = express();
const passport = require('passport');
const user = require('./passport-serialize');
const routes = require('./routes');
//lots of middleware
//session middleware
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(user.serialize);
passport.deserializeUser(user.deserialize);
app.use('/api', routes);
//actual server, more stuff
passport-serialize.js
//include Account model
const user = {
serialize: (user, done) => {
done(null, user.username)
},
deserialize: (username, done) => {
Account.findOne({'username': username}, function(err, user) {
done(err, user);
}
}
module.exports = user;
routes.js
const express = require('express');
const router = new express.Router();
const passport = require('./strategies');
//many routes
router.post('/login', passport.authenticate('local-login'), function(req, res) {
console.log("executed login!");
console.log(req.user);
});
router.get('/test', function(req, res) {
console.log(req.user);
res.json(req.user);
});
module.exports = router;
strategies.js
const passport = require('passport');
const LocalStrategy = require('whatever the package is');
//Account model
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
}, function(req, username, password, done) { // callback with email and password from our form
console.log("doing local login");
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
Account.findOne({ 'username' : username }, function(err, user) {
var thisuser = user;
console.log("query account is done");
// if there are any errors, return the error before anything else
if (err) {
console.log("error occured");
return done(err);
}
console.log("if user exist check");
// if no user is found, return the message
if (!user)
return done(null, false,'No user found.');
// req.flash is the way to set flashdata using connect-flash
console.log("checking password");
// if the user is found but the password is wrong
} else if (!user.validPassword(password)) {
console.log("password is not valid");
return done(null, false, 'Oops! Wrong password.');
// create the loginMessage and save it to session as flashdata
}
console.log("all good! logging in!");
// all is well, return successful user
return done(null, thisuser);
});
}));
module.exports = passport;
I've added nodejs passport login to my app and everything worked fine, until I committed changes to production. The issue is pretty wired: user is randomly changes sometimes when I reload the page.
Here is my app.js code:
var mysql = require('promise-mysql');
var passport = require('passport');
var app = express();
app.use(cookieParser())
app.use(session({
secret: 'keyboard cat',
maxAge: 60 * 5,
resave: false,
saveUninitialized: false
}))
app.use(passport.initialize());
app.use(passport.session());
mysql.createConnection(dbConfig.connection).then(
function (connection) {
require('./config/passport')(passport, connection); // pass passport for configuration
}
);
Here is what I have in configs/passport.js
var LocalStrategy = require('passport-local').Strategy;
var bcrypt = require('bcrypt-nodejs');
module.exports = function (passport, connection) {
passport.serializeUser(function (user, done) {
done(null, user.name);
});
// used to deserialize the user
passport.deserializeUser(function (name, done) {
connection.query("SELECT * FROM users WHERE name = ? ", [name])
.then(function (rows) {
done(null, rows[0]);
})
.catch(function (err) {
console.log("Error getting user form DB: ", err);
done(err);
});
});
passport.use(
'local-login',
new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function (req, username, password, done) { // callback with email and password from our form
connection.query("SELECT * FROM users WHERE username = ?", [username])
.then(function (rows) {
if (!rows.length) {
done(null, false); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
else if (!bcrypt.compareSync(password, rows[0].password)) {
done(null, false); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
}
else {
done(null, rows[0]);
}
})
.catch(function (err) {
console.log("Login Failed: ", err.body);
done(err);
});
})
);
};
And this is what I have in every route file:
router.all('*', function (req, res, next) {
if (req.isAuthenticated()) {
user.init(req.user);
next(); // pass control to the next handler
}
else {
res.redirect('/');
}
});
Does anyone had similar issue? Seems like I've made some simple and stupid error, because google can't find similar issues.
Thanks!
You're executing two different queries:
// passport.deserializeUser()
connection.query("SELECT * FROM users WHERE name = ? ", [name])
// In the Passport verification handler
connection.query("SELECT * FROM users WHERE username = ?", [username])
My guess would be that name isn't unique, and that you want to use username everywhere.
As an aside: you're setting maxAge to 300 milliseconds.
Turns out to be issue with objects storing by node js in memory. I don't fully understand how this is happened, but this is what I found.
I stored req.user in userModel object, and if there are a lot of requests on server, this userModel object sometimes gets messed up with data from different users.
The solution was to directly user req.user everywhere.
I am trying to use passport local auth with sequelize . When I submit login form, the request/respond cycle never end and there is no error message in the terminal .
Here are all of my codes:
app.js
var Sequelize = require('sequelize'),
express = require('express'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
User = require('./models/users');
........ and other imports.....
//route import , model injection
var auth = require('./routes/auth')(User);
.......................
app.use(session({
store: new RedisStore(),
secret: 'keyboard cat',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
console.log(user);
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id).then(function(user){
done(null, user);
}).catch(function(e){
done(e, false);
});
});
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({where: {username: username}}).then(function(err, user) {
if (err) { return done(err); }
if (!user) {
console.log('Incorrect username.');
return done(null, false, { message: 'Incorrect username.' });
} else if (password != user.password) {
console.log('Incorrect password');
return done(null, false, { message: 'Incorrect password.' });
} else {
console.log('ok');
done(null, user);
}
});
}
));
and routes/auth.js :
var express = require('express'),
passport = require('passport');
var routes = function(User) {
var router = express.Router();
// routes for registration
router.route('/register')
.get(function(req, res) {
res.render('register');
})
.post(function(req, res) {
User.count().then(function(number) {
if (number >= 1) {
res.redirect('/auth/login');
} else {
User.create({
username: req.body.username,
password: req.body.password
});
res.redirect('/auth/login');
}
});
});
//routes for login
router.route('/login')
.get(function(req, res) {
res.render('login');
})
.post(function(req, res) {
passport.authenticate('local', { successRedirect: '/dashboard',
failureRedirect: '/auth/login' });
});
return router;
};
module.exports = routes;
Why does the request/response cycle never end?
Your current middleware definition for './login' POST is incorrect and does not send a response, which is why it doesn't end (until it times out).
Instead of calling passport.authenticate in a middleware function, the result of calling passport.authenticate should be used as middleware itself. I suggest the following:
router.route('/login')
.get(function(req, res) {
res.render('login');
})
.post(passport.authenticate('local', { successRedirect: '/dashboard',
failureRedirect: '/auth/login' });
);
See http://passportjs.org/docs/authenticate for an example.
Race condition in registration code
You didn't ask about this, but there is a race condition in your middleware for './register' POST.
User.create returns a promise for saving the created user. Until that promise is resolved there is no guarantee that the user exists in the backing datastore. However, immediately after calling create, your code redirects to the login endpoint which would query the database for that user.
Here is some code that avoids this problem:
User.create({ ... })
.then(function() {
res.redirect('/auth/login');
})
.catch(function(err) {
// Handle rejected promise here
})
The catch is included because it is always good practice to handle rejected promises and thrown exceptions.
I've implemented a registration form in a modal to save a user to my database and subsequently log them in. The user is indeed saved to my database, but the user object remains undefined.
Here is my setup in app.js
var express = require('express'),
app = express(),
exphbs = require('express-handlebars'),
passport = require('passport'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
morgan = require('morgan'),
methodOverride = require('method-override'),
session = require('express-session'),
funct = require('./app/functions'),
dbconfig = require('./app/config/database'),
db = require('orchestrate')(dbconfig.db),
LocalStrategy = require('passport-local');
//===============PASSPORT===============
passport.serializeUser(function(user, done) {
console.log("serializing " + user.username);
done(null, user.username);
});
passport.deserializeUser(function(obj, done) {
console.log("deserializing " + obj);
done(null, obj);
});
passport.use('local-signup', new LocalStrategy(
{passReqToCallback: true}, //allows us to pass back the request to the callback
function (req, username, password, done) {
funct.localReg(username, password)
.then(function (user) {
if (user) {
console.log("REGISTERED: " + user.username);
req.login(user, function(err) {
if (err) {
console.log(err);
}
});
done(null, user);
}
if (!user) {
console.log("COULD NOT REGISTER");
req.session.error = 'That username is already in use, please try a different one.'; //inform user could not log them in
done(null, user);
}
})
.fail(function (err) {
console.log(err.body);
});
}
));
//===============EXPRESS================
// Configure Express
app.use(morgan('combined')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(session({secret: 'MisfireMedia_Appubator', saveUninitialized: true, resave: true}));
app.use(passport.initialize());
app.use(passport.session());
app.get('/about', function (req, res) {
res.render('about');
});
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/about',
failureRedirect: '/'
})
);
And here's my function.js (where funct.localReg is defined)
var bcrypt = require('bcrypt'),
Q = require('q'),
dbconfig = require('./config/database'), //config file contains all tokens and other private info
db = require('orchestrate')(dbconfig.db); //config.db holds Orchestrate token
exports.localReg = function (username, password) {
console.log(password);
var deferred = Q.defer();
var user = {
"username": username,
"password": password
};
//check if username is already assigned in our database
db.get('users', username)
.then(function (result){ //case in which user already exists in db
console.log('username already exists');
deferred.resolve(false); //username already exists
})
.fail(function (result) {//case in which user does not already exist in db
console.log(result.body);
if (result.body.message == 'The requested items could not be found.'){
console.log('Username is free for use');
db.put('users', username, user)
.then(function () {
console.log("USER: " + user);
deferred.resolve(user);
})
.fail(function (err) {
console.log("PUT FAIL:" + err.body);
deferred.reject(new Error(err.body));
});
} else {
deferred.reject(new Error(result.body));
}
});
return deferred.promise;
};
The modal form is being submitted with code in custom.js:
$(function() {
$("button#signupsubmit").click(function(){
$.ajax({
type: "POST",
url: "/signup",
data: $('form#signup').serialize(),
success: function(msg){
$("#myModal").modal('hide');
},
error: function(){
alert("failure");
}
});
});
});
However, once the modal hides (on successful post) I try to log out the user and get "user is not defined". Also, attempting to display the username with
{{#if user}}
<p>Hi, {{user.username}}</p>
{{/if}}
just gives me "Hi,"
So any ideas on why I can't access the user? I'm not especially experienced with Node, Express, or Passport and I don't quite fully understand what's going on yet because most of this is copypasta from tutorials and whatnot (specifically this one). Any suggestions on what to look at or what I'm missing would be most excellent.
If i understand correctly you are exposing REST api from express and consuming it in client side using jQuery. After successful login user data are cached in passport session and i think you are returning data to jQuery which temporarily holds the data.
One possibility is that when you are perform any action in client side, (unless you keep calling backend to fetch data from passport session) the data is flushed out, it is no more there so that's the reason you are getting it as undefined.
In such cases best you can do or i would say that most of the modern websites are designed such that they store user session data as a json web token(JWT) in browser's local storage in encoded form. You can read about JWT here. You can also see some example as in how exactly the encoded string looks like and can play around with it here.
When user successfully logs in, write the data in browser's local storage and when he logs out, clear the token from local storage. This will save you from making unnecessary calls back and forth to server.
I actually implemented it using AngularJS here, concept is same doesn't matter which framework we use.
As it turns out, the issue was with the serialization. I was serializing user.username instead of just user therefore user.username didn't exist.
I changed the serialize function to
passport.serializeUser(function(user, done) {
console.log("serializing " + user.username);
done(null, user);
});
and also made sure to change my route render from
res.render('about');
to
res.render('about', {user: req.user});
which allowed me to display the username in the about handlebars file as such
{{user.username}}