DEV Community

Manoj Gohel
Manoj Gohel

Posted on

PASETO: A New Era of Token-Based Authentication with Node.js and Express

PASETO (Platform-Agnostic Security Tokens) is a modern alternative to JWT (JSON Web Tokens) that focuses on security and simplicity. Here's an example of how to use PASETO for token-based authentication in JavaScript.

Image description

Setup

  1. Install the necessary libraries:
    • Use the paseto.js library for PASETO.
    • For simplicity, we'll use Node.js and Express to demonstrate a server-side implementation.
npm install paseto express body-parser
Enter fullscreen mode Exit fullscreen mode
  1. Create the server:
// server.js
const express = require('express');
const bodyParser = require('body-parser');
const { V4 } = require('paseto');
const { generateKeyPair } = require('paseto/dist/lib/crypto/pair');

const app = express();
const port = 3000;

app.use(bodyParser.json());

let privateKey;
let publicKey;

(async () => {
  const keyPair = await generateKeyPair('v4.public');
  privateKey = keyPair.secretKey;
  publicKey = keyPair.publicKey;
})();

// Middleware to verify PASETO token
const authenticateToken = async (req, res, next) => {
  const token = req.header('Authorization').replace('Bearer ', '');
  try {
    const payload = await V4.verify(token, publicKey);
    req.user = payload;
    next();
  } catch (err) {
    res.status(401).send('Unauthorized');
  }
};

// Login route to generate PASETO token
app.post('/login', async (req, res) => {
  const { username, password } = req.body;
  // Replace with your own user verification logic
  if (username === 'admin' && password === 'password') {
    const token = await V4.sign({ username }, privateKey, { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).send('Invalid credentials');
  }
});

// Protected route
app.get('/protected', authenticateToken, (req, res) => {
  res.json({ message: 'This is a protected route', user: req.user });
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});
Enter fullscreen mode Exit fullscreen mode

Explanation

  1. Key Pair Generation:

    • The server generates a key pair for signing and verifying PASETO tokens using generateKeyPair('v4.public').
  2. Login Route:

    • The /login route verifies the username and password.
    • If valid, it generates a PASETO token using V4.sign and sends it to the client.
  3. Authentication Middleware:

    • The authenticateToken middleware extracts the token from the Authorization header.
    • It verifies the token using V4.verify and attaches the payload to the req.user object.
  4. Protected Route:

    • The /protected route uses the authenticateToken middleware to ensure only authenticated users can access it.

Client-Side Example

Here is a simple client-side example using fetch:

<!DOCTYPE html>
<html>
<head>
  <title>PASETO Authentication</title>
</head>
<body>
  <h1>PASETO Authentication Example</h1>
  <button id="loginButton">Login</button>
  <button id="protectedButton">Access Protected Route</button>
  <script>
    document.getElementById('loginButton').addEventListener('click', async () => {
      const response = await fetch('http://localhost:3000/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ username: 'admin', password: 'password' })
      });
      const data = await response.json();
      localStorage.setItem('token', data.token);
      alert('Logged in and token stored in local storage');
    });

    document.getElementById('protectedButton').addEventListener('click', async () => {
      const token = localStorage.getItem('token');
      const response = await fetch('http://localhost:3000/protected', {
        method: 'GET',
        headers: {
          'Authorization': `Bearer ${token}`
        }
      });
      const data = await response.json();
      alert(JSON.stringify(data));
    });
  </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Explanation

  1. Login Button:

    • Sends a POST request to the /login endpoint with the username and password.
    • Stores the received token in localStorage.
  2. Protected Button:

    • Sends a GET request to the /protected endpoint with the token in the Authorization header.
    • Displays the response data.

This example demonstrates how to use PASETO for token-based authentication in a simple Node.js application with client-side interaction.

Top comments (0)