DEV Community

Alok Kumar
Alok Kumar

Posted on

Authentication and Authorization in Node.js

Authentication and authorization are really important for websites. They make sure that the people using the site are who they say they are, and that they can only do things they're supposed to do. In this blog, we'll explain what these terms mean and show you how to use them in a Node.js website.

Authentication vs. Authorization

Before diving into implementation details, let's clarify the distinction between authentication and authorization:

  • Authentication: It is like showing your ID to prove who you are. It's the process of making sure that the person using a website is really the person they say they are, by checking things like their username and password.

  • Authorization: Once a user is authenticated, authorization determines what actions they are allowed to perform within the application. It defines access permissions based on the user's identity and role.

Implementing Authentication and Authorization in Node.js

To demonstrate authentication and authorization in Node.js, we'll use the popular express framework along with jsonwebtoken for generating and verifying JSON Web Tokens (JWT).

Step 1: Setting Up the Node.js Project

First, let's initialize a new Node.js project and install the necessary dependencies:

mkdir node-authentication-authorization
cd node-authentication-authorization
npm init -y
npm install express jsonwebtoken bcrypt
Enter fullscreen mode Exit fullscreen mode

Step 2: Creating the Authentication System

We'll create routes for user registration, login, and profile access. We'll also generate JWTs for authenticated users.

// index.js
const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');

const app = express();
app.use(express.json());

// Dummy user database
const users = [];

// Register a new user
app.post('/register', async (req, res) => {
    try {
        const hashedPassword = await bcrypt.hash(req.body.password, 10);
        const user = { username: req.body.username, password: hashedPassword };
        users.push(user);
        res.status(201).send("User registered successfully.");
    } catch {
        res.status(500).send("Error registering user.");
    }
});

// Login
app.post('/login', async (req, res) => {
    const user = users.find(user => user.username === req.body.username);
    if (user == null) {
        return res.status(400).send("User not found.");
    }
    try {
        if (await bcrypt.compare(req.body.password, user.password)) {
            const accessToken = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET);
            res.json({ accessToken: accessToken });
        } else {
            res.status(401).send("Incorrect password.");
        }
    } catch {
        res.status(500).send("Error logging in.");
    }
});

// Profile route
app.get('/profile', authenticateToken, (req, res) => {
    res.json(req.user);
});

// Middleware to authenticate token
function authenticateToken(req, res, next) {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];
    if (token == null) return res.sendStatus(401);

    jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
        if (err) return res.sendStatus(403);
        req.user = user;
        next();
    });
}

app.listen(3000, () => {
    console.log('Server started on http://localhost:3000');
});

Enter fullscreen mode Exit fullscreen mode

Step 3: Protecting Routes with Authorization

We'll implement a simple authorization mechanism to restrict access to certain routes based on user roles.

// index.js

// Define user roles
const roles = {
    admin: 'admin',
    user: 'user'
};

// Example protected route accessible only by admin
app.get('/admin', authenticateToken, (req, res) => {
    if (req.user.role !== roles.admin) return res.status(403).send("Forbidden");
    res.send("Admin panel");
});
Enter fullscreen mode Exit fullscreen mode

Step 4: Testing the Authentication and Authorization

You can test the authentication and authorization endpoints using tools like Postman or by making HTTP requests using curl.

# Register a new user
curl -X POST -H "Content-Type: application/json" -d '{"username":"user1", "password":"password123"}' http://localhost:3000/register

# Login
curl -X POST -H "Content-Type: application/json" -d '{"username":"user1", "password":"password123"}' http://localhost:3000/login

# Access profile with obtained access token
curl -H "Authorization: Bearer <ACCESS_TOKEN>" http://localhost:3000/profile

# Access admin route (assuming admin role)
curl -H "Authorization: Bearer <ACCESS_TOKEN>" http://localhost:3000/admin

Enter fullscreen mode Exit fullscreen mode

Conclusion

In this guide, we've looked at how to make sure the right people can access your web app securely. We talked about two important ideas: authentication (making sure users are who they say they are) and authorization (giving them the right permissions). I showed you how to set this up in a Node.js app using something called JSON Web Tokens. By following these steps, you can make sure your web app keeps sensitive information safe and gives users a good experience.

Top comments (0)