Implementing authentication is a crucial step in securing your web application. Bun, a modern JavaScript runtime, offers efficient tools to set up authentication seamlessly. This tutorial guides you through the process of integrating Bun Authentication into your web app.

Prerequisites

  • Node.js and Bun installed on your development machine
  • A basic understanding of JavaScript and Bun
  • Access to a code editor like VS Code
  • A running web server or local development environment

Step 1: Initialize Your Bun Project

Start by creating a new directory for your project and initialize it with Bun.

mkdir my-bun-auth-app
cd my-bun-auth-app
bun init

This sets up a basic Bun project structure with package.json and necessary files.

Step 2: Install Authentication Dependencies

For authentication, you can use libraries like bcrypt for password hashing and a JWT library for token management. Install them using Bun.

bun add bcrypt jsonwebtoken

Step 3: Create User Model and Storage

Set up a simple user model and storage mechanism. For demonstration, use an in-memory store or a database connection as needed.

// userModel.js
const users = [];

export function createUser(username, passwordHash) {
  const user = { id: Date.now(), username, passwordHash };
  users.push(user);
  return user;
}

export function findUserByUsername(username) {
  return users.find(user => user.username === username);
}

Step 4: Implement Registration Endpoint

Create a registration route that hashes the password and stores the user.

// register.js
import { createUser, findUserByUsername } from './userModel.js';
import bcrypt from 'bcrypt';

export async function register(req, res) {
  const { username, password } = req.body;
  if (findUserByUsername(username)) {
    return res.status(400).json({ message: 'User already exists' });
  }
  const passwordHash = await bcrypt.hash(password, 10);
  const user = createUser(username, passwordHash);
  res.status(201).json({ userId: user.id });
}

Step 5: Implement Login Endpoint

Validate user credentials and generate a JWT token upon successful login.

// login.js
import { findUserByUsername } from './userModel.js';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';

const SECRET_KEY = 'your-secret-key';

export async function login(req, res) {
  const { username, password } = req.body;
  const user = findUserByUsername(username);
  if (!user) {
    return res.status(401).json({ message: 'Invalid credentials' });
  }
  const match = await bcrypt.compare(password, user.passwordHash);
  if (!match) {
    return res.status(401).json({ message: 'Invalid credentials' });
  }
  const token = jwt.sign({ userId: user.id }, SECRET_KEY, { expiresIn: '1h' });
  res.json({ token });
}

Step 6: Protect Routes with Middleware

Create middleware to verify JWT tokens for protected routes.

// authMiddleware.js
import jwt from 'jsonwebtoken';

const SECRET_KEY = 'your-secret-key';

export function authenticate(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  if (!token) {
    return res.status(401).json({ message: 'Missing token' });
  }
  jwt.verify(token, SECRET_KEY, (err, user) => {
    if (err) {
      return res.status(403).json({ message: 'Invalid token' });
    }
    req.user = user;
    next();
  });
}

Step 7: Integrate Authentication into Your App

Use the registration and login endpoints, then protect sensitive routes with the middleware.

// app.js
import express from 'express';
import { register } from './register.js';
import { login } from './login.js';
import { authenticate } from './authMiddleware.js';

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

app.post('/register', register);
app.post('/login', login);

app.get('/protected', authenticate, (req, res) => {
  res.json({ message: 'Protected content', userId: req.user.userId });
});

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

Conclusion

By following these steps, you can implement secure authentication in your Bun-based web app. Remember to handle user data responsibly and consider integrating a database for production environments. Happy coding!