Home >Web Front-end >JS Tutorial >User Authentication API with Express, JWT, Bcrypt, and MySQL

User Authentication API with Express, JWT, Bcrypt, and MySQL

DDD
DDDOriginal
2024-11-05 13:32:02993browse

User Authentication API with Express, JWT, Bcrypt, and MySQL

This application is a simple authentication server built with Express, using JSON Web Tokens (JWT) for session management and bcrypt for securely storing passwords. Users can register and log in to access protected routes. MySQL is used for storing user data.

Technologies Used

1. Express.js: Web framework for handling routes and middleware.
2. bcrypt.js: Library for hashing passwords securely.
3. jsonwebtoken: Library for creating and verifying JWT tokens.
4. mysql2: MySQL client for Node.js with support for Promises.
5. cookie-parser: Middleware for parsing cookies.

Code Breakdown

1. Import Required Libraries

const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const cookieParser = require('cookie-parser');
const mysql = require('mysql2/promise');
  • express: Provides functions to create routes and handle HTTP requests.
  • jsonwebtoken: Used to create and verify JWTs for user sessions.
  • bcryptjs: Used for hashing passwords before storing them in the database.
  • cookie-parser: Middleware to parse cookies from incoming HTTP requests.
  • mysql2/promise: MySQL client with promise support, allowing asynchronous operations.

2. Initialize Express App and Define Constants

const app = express();
const PORT = 3000;
const JWT_SECRET = 'your_jwt_secret_key';
  • app: The Express application instance.
  • PORT: The port the server will listen on.
  • JWT_SECRET: A secret key used to sign JWTs. Replace this with a secure, randomly generated value in production.

3. Database Connection Setup

const db = await mysql.createConnection({
    host: 'localhost',
    user: 'your_mysql_user',
    password: 'your_mysql_password',
    database: 'user_auth'
});

  • db: The MySQL database connection object.
  • mysql.createConnection(): Establishes a connection to the MySQL database using async/await, which is needed for non-blocking queries.
  • host: Yout MySql application hostname, If you are running it on localhost, put localhost only, if you have deployed your MySql to a server, use the server hostname with PORT.
  • user: Your MySql Username
  • password: Your MySql Password
  • database: The Database name

4. Middleware Setup

app.use(express.json());
app.use(cookieParser());
  • express.json(): Middleware to parse JSON request bodies.
  • cookieParser(): Middleware to parse cookies, allowing us to read cookies from req.cookies.

5. Register Route

/register
This route registers a new user by hashing their password and saving it in the database.

const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const cookieParser = require('cookie-parser');
const mysql = require('mysql2/promise');
  • db.execute(): Executes a query to check if a user with the given email already exists. If they do, return a 400 status.
  • bcrypt.hash(password, 10): Hashes the password with a salt rounds value of 10 for security.
  • db.execute() (Insert): Saves the user's name, email, and hashed password in the database.

6. Login Route

/login
This route logs in an existing user by checking their credentials and generating a JWT token.

const app = express();
const PORT = 3000;
const JWT_SECRET = 'your_jwt_secret_key';
  • bcrypt.compare(password, user.password): Verifies if the hashed password matches the one stored in the database.
  • jwt.sign(): Creates a JWT that includes user information (e.g., ID, name, and email). The token expires in 1 hour. jwt.sign() method takes two arguments payload, JWT_SECRET, options(optional)
  • res.cookie(): Sets a cookie with the JWT, secured by httpOnly (only accessible by the server) and sameSite settings.

7. JWT Verification Middleware

The verifyToken middleware ensures that only requests with a valid JWT token can access protected routes.

const db = await mysql.createConnection({
    host: 'localhost',
    user: 'your_mysql_user',
    password: 'your_mysql_password',
    database: 'user_auth'
});

  • req.cookies.token: Extracts the token from cookies.
  • jwt.verify(token, JWT_SECRET): Verifies the token using the JWT secret key. If valid, decoded **contains the token’s payload, which is assigned to **req.user.
  • next(): Proceeds to the next middleware if the token is valid.

8. Protected Route - /protected

A sample protected route accessible only to authenticated users. It returns a personalized greeting using the user’s name from the token.

app.use(express.json());
app.use(cookieParser());
  • verifyToken: Middleware applied to check the user’s authentication status.
  • req.user.name: Accesses the user’s name from the decoded JWT payload.

9. Start the Server

The server listens on the defined PORT.

app.post('/register', async (req, res) => {
    const { name, email, password } = req.body;

    try {
        // Check if user already exists
        const [rows] = await db.execute('SELECT * FROM users WHERE email = ?', [email]);
        if (rows.length > 0) {
            return res.status(400).json({ message: 'User already exists' });
        }

        // Hash the password
        const hashedPassword = await bcrypt.hash(password, 10);

        // Save the user in the database
        await db.execute('INSERT INTO users (name, email, password) VALUES (?, ?, ?)', [name, email, hashedPassword]);
        res.status(201).json({ message: 'User registered successfully!' });
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: 'Server error' });
    }
});

Full Code

app.post('/login', async (req, res) => {
    const { email, password } = req.body;

    try {
        // Find user
        const [rows] = await db.execute('SELECT * FROM users WHERE email = ?', [email]);
        const user = rows[0];
        if (!user) {
            return res.status(400).json({ message: 'User not found' });
        }

        // Check password
        const isMatch = await bcrypt.compare(password, user.password);
        if (!isMatch) {
            return res.status(400).json({ message: 'Invalid credentials' });
        }

        // Create JWT token
        const token = jwt.sign({ id: user.id, name: user.name, email: user.email }, JWT_SECRET, { expiresIn: '1h' });

        // Set JWT in cookie
        res.cookie('token', token, {
            httpOnly: true,
            secure: process.env.NODE_ENV === 'production',
            sameSite: 'Strict',
            maxAge: 3600000 // 1 hour
        });

        res.json({ message: 'Logged in successfully!' });
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: 'Server error' });
    }
});

Summary

This application:

  1. Allows user registration by hashing passwords and storing user data in MySQL.
  2. Supports secure login with JWT authentication.
  3. Uses cookies to store the JWT on the client side.
  4. Provides middleware for verifying JWTs before granting access to protected routes.

The above is the detailed content of User Authentication API with Express, JWT, Bcrypt, and MySQL. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn