Skip to content

๐Ÿ”‘ User authentication

Aidan98 edited this page Apr 6, 2022 · 5 revisions

Passport logo


What is authentication?

User authentication just like password hashing is a key feature within our web app. Without these features a login an registration is useless, without hashing passwords would be saved in plain text which is a HUGE no no and without authentication users can access areas of the web app without logging in (pages such as teacher and admin profiles).

Passport

Passport is authentication middleware for Node. There are over 500 ways to authenticate using Passport called strategies. Strategy we will be using is called passport-local as we will using the users username and password to authenticate them.

Usage

We start by installing this node module by running $ npm install passport-local in our terminal and requiring it in our code: const passport = require('passport');. Next we write the middleware for Passport.js:

app.use(passport.initialize());
app.use(passport.session());

Local strategy

Now we can start writing the code for user authentication, here is an example of how your code can look like. We start by specifying which authentication strategy we are using. Next we check the username the user filled in in the input field to see if it matches any username within the database, if the username isn't found a message will display saying that that username has not been registered. When a user is found it will check if the input password matches the password within the database, when the passwords match the user logs in and a session is established it does this by serializing the user ID, if the user reloads the page or change pages the ID is used to find the user and maintain the session.

const localStrategy = require('passport-local').Strategy;

passport.use(
        new localStrategy({
            usernameField: 'username'
        }, (username, password, done) => {
            // Match user
            User.findOne({
                username: username
            }).then(async user => {
                if (!user) {
                    console.log('username not found');
                    return done(null, false, {
                        message: 'That username is not registered'
                    });
                }

                const match = await argon2.verify(user.password, password);
                if (match) {
                    return done(null, user);
                } else {
                    console.log('password incorrect');
                    return done(null, false, {
                        message: 'Password is incorrect'
                    });
                }
            });
        })
    );

    passport.serializeUser((user, done) => {
        done(null, user.id);
    });

    passport.deserializeUser((id, done) => {
        User.findById(id, (err, user) => {
            done(err, user);
        });
    });
router.post('/login', (req, res, next) => {
    let errors = [];
    passport.authenticate('local', {
        successRedirect: '/',
        failureRedirect: '/users/login',
    })(req, res, next);
    errors.push({ msg: 'email not found' });
});

Protecting routes

We'll need to protect the routes, in order to ensure visitors to our web app don't have access to pages only logged in users have access to. we do this by checking if the person viewing the web app is authenticated:

ensureAuthenticated: function(req, res, next) {
        if (req.isAuthenticated()) {
            return next();
        }
        res.redirect('/users/login');
    }

And adding ensureAuthenticated to our router.get. Now if the user tries to access this route without logging in it will redirect to the login page.

router.get(`/courses`, ensureAuthenticated, (req, res) => {

} 

Sources