Express.js: Implementing User Authentication
User authentication is a crucial feature for any web application that requires user accounts. In this tutorial, we will be implementing user authentication with the Express.js framework, using Passport.js for authentication and MongoDB for storing user information.
Syntax
Installation:
$ npm install express passport passport-local bcryptjs express-session connect-mongo mongoose
Setup:
const express = require('express');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');
const session = require('express-session');
const connectMongo = require('connect-mongo');
const mongoose = require('mongoose');
const app = express();
// Database Connection
mongoose.connect('mongodb://localhost:27017/myapp');
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error'));
db.once('open', function() {
// We're connected!
});
// User Model
const User = mongoose.model('User', {
username: String,
password: String
});
// Passport Configuration
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.' });
}
bcrypt.compare(password, user.password, function(err, res) {
if (res) {
return done(null, user);
} else {
return done(null, false, { message: 'Incorrect password.' });
}
});
});
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
// Express Middleware Configuration
const MongoStore = connectMongo(session);
const sessionStore = new MongoStore({
mongooseConnection: mongoose.connection,
collection: 'sessions'
});
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(session({
secret: 'myappsecret',
resave: false,
saveUninitialized: false,
store: sessionStore
}));
app.use(passport.initialize());
app.use(passport.session());
// Authentication Routes
app.get('/login', function(req, res) {
res.send(`
<h1>Login</h1>
<form action="/login" method="post">
<div>
<label>Username:</label>
<input type="text" name="username"/>
</div>
<div>
<label>Password:</label>
<input type="password" name="password"/>
</div>
<div>
<input type="submit" value="Log In"/>
</div>
</form>
`);
});
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
}
);
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
app.get('/', function(req, res) {
if (req.isAuthenticated()) {
res.send(`<h1>Hello, ${req.user.username}!</h1><a href="/logout">Logout</a>`);
} else {
res.send(`
<h1>Welcome!</h1>
<p><a href="/login">Login</a> to view your profile.</p>
`);
}
});
// Start Server
app.listen(3000, function() {
console.log('Server started');
});
Example
Login
http://localhost:3000/login
A login form will be displayed on the page.
Username: admin
Password: password123
After submitting the form, the user will be redirected to the homepage if authentication is successful. Otherwise, the user will be redirected back to the login page.
Logout
http://localhost:3000/logout
The user will be logged out and redirected to the homepage.
Homepage
http://localhost:3000/
If the user is authenticated, the user's name will be displayed on the page along with a logout button. Otherwise, a welcome message and a link to the login page will be displayed.
Explanation
This example uses Passport.js for authentication and MongoDB for user information storage.
The authentication process consists of three main parts:
- Configuration of the authentication strategy (Local Strategy).
- Configuration of the Express.js middleware.
- Definition of the authentication routes.
The authentication strategy is defined using the passport.use
method. The Local Strategy requires the definition of the username
and password
fields. The strategy takes a callback function that checks if the user exists in the database and compares the password hashes.
The Express.js middleware consists of several packages such as express-session
and connect-mongo
. These packages are used to configure session management and store session data in MongoDB.
The authentication routes define the login, logout, and homepage routes. The login route displays a login form and authenticates the user using passport.authenticate
. The logout route logs the user out and redirects them to the homepage. The homepage route displays a welcome message and the user's name if authenticated.
Use
This code can be used as a starting point for web applications that require user authentication. However, it is important to note that this code only serves as an example and should not be used as-is in production environments.
It is recommended to use SSL/TLS encryption to secure the application's communication. Also, it is important to properly validate user input to prevent security vulnerabilities such as SQL injection and cross-site (XSS).
Important Points
- User authentication is an important feature for any web application requiring user accounts.
- Passport.js is a popular authentication library for Node.js and Express.js.
- MongoDB is a NoSQL database that can be used to store user account information.
- It is important to properly validate user input to prevent security vulnerabilities.
Summary
User authentication is a crucial feature for any web application that requires user accounts. In this tutorial, we implemented user authentication with Express.js and Passport.js, using MongoDB for storing user information. We went over the authentication process and also discussed some important such as SSL/TLS encryption and input validation.