首页  >  文章  >  web前端  >  使用 Express、JWT、Bcrypt 和 MySQL 的用户身份验证 API

使用 Express、JWT、Bcrypt 和 MySQL 的用户身份验证 API

DDD
DDD原创
2024-11-05 13:32:02940浏览

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

此应用程序是一个使用 Express 构建的简单身份验证服务器,使用 JSON Web 令牌 (JWT) 进行会话管理,并使用 bcrypt 安全存储密码。用户可以注册并登录来访问受保护的路由。 MySQL用于存储用户数据。

使用的技术

1。 Express.js:用于处理路由和中间件的 Web 框架。
2. bcrypt.js:用于安全地散列密码的库。
3. jsonwebtoken:用于创建和验证 JWT 令牌的库。
4. mysql2:Node.js 的 MySQL 客户端,支持 Promises。
5. cookie-parser:用于解析 cookie 的中间件。

代码分解

1。导入所需的库

const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const cookieParser = require('cookie-parser');
const mysql = require('mysql2/promise');
  • express:提供创建路由和处理HTTP请求的功能。
  • jsonwebtoken:用于为用户会话创建和验证 JWT。
  • bcryptjs:用于在将密码存储到数据库之前对其进行哈希处理。
  • cookie-parser:从传入的 HTTP 请求中解析 cookie 的中间件。
  • mysql2/promise:支持 Promise 的 MySQL 客户端,允许异步操作。

2. 初始化 Express App 并定义常量

const app = express();
const PORT = 3000;
const JWT_SECRET = 'your_jwt_secret_key';
  • app:Express 应用程序实例。
  • PORT:服务器将侦听的端口。
  • JWT_SECRET:用于签署 JWT 的密钥。将其替换为生产中安全、随机生成的值。

3. 数据库连接设置

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

  • db:MySQL 数据库连接对象。
  • mysql.createConnection():使用async/await建立与MySQL数据库的连接,这是非阻塞查询所需要的。
  • host:您的MySql应用程序主机名,如果您在本地主机上运行它,则仅输入本地主机,如果您已将MySql部署到服务器,请使用带有PORT的服务器主机名。
  • user:您的 MySql 用户名
  • 密码:您的MySql密码
  • 数据库:数据库名称

4. 中间件设置

app.use(express.json());
app.use(cookieParser());
  • express.json():解析 JSON 请求体的中间件。
  • cookieParser():解析cookie的中间件,允许我们从req.cookies中读取cookie。

5. 注册路线

/注册
该路由通过散列密码并将其保存在数据库中来注册新用户。

const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const cookieParser = require('cookie-parser');
const mysql = require('mysql2/promise');
  • db.execute():执行查询以检查具有给定电子邮件的用户是否已存在。如果他们这样做,则返回 400 状态。
  • bcrypt.hash(password, 10):为了安全起见,使用盐舍入值 10 对密码进行哈希处理。
  • db.execute()(插入):将用户名、电子邮件和散列密码保存在数据库中。

6. 登录路径

/登录
此路由通过检查现有用户的凭据并生成 JWT 令牌来登录现有用户。

const app = express();
const PORT = 3000;
const JWT_SECRET = 'your_jwt_secret_key';
  • bcrypt.compare(password, user.password):验证散列密码是否与数据库中存储的密码匹配。
  • jwt.sign():创建包含用户信息(例如 ID、姓名和电子邮件)的 JWT。令牌将在 1 小时后过期。 jwt.sign() 方法采用两个参数 payloadJWT_SECREToptions(可选)
  • res.cookie():使用 JWT 设置 cookie,由 httpOnly(仅由服务器访问)和 SameSite 设置保护。

7.JWT验证中间件

verifyToken 中间件确保只有具有有效 JWT 令牌的请求才能访问受保护的路由。

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

  • req.cookies.token:从cookie中提取令牌。
  • jwt.verify(token, JWT_SECRET):使用 JWT 密钥验证令牌。如果有效,解码**包含令牌的有效负载,该负载被分配给 **req.user.
  • next():如果令牌有效,则继续到下一个中​​间件。

8. 受保护的路由 - /protected

仅经过身份验证的用户可以访问的受保护路由示例。它使用令牌中的用户名返回个性化问候语。

app.use(express.json());
app.use(cookieParser());
  • verifyToken:用于检查用户身份验证状态的中间件。
  • req.user.name:从解码的 JWT 负载中访问用户名。

9. 启动服务器

服务器监听定义的端口。

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' });
    }
});

完整代码

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' });
    }
});

概括

此应用程序:

  1. 允许通过散列密码进行用户注册并将用户数据存储在 MySQL 中。
  2. 支持通过 JWT 身份验证进行安全登录。
  3. 使用cookie在客户端存储JWT。
  4. 提供中间件,用于在授予受保护路由的访问权限之前验证 JWT。

以上是使用 Express、JWT、Bcrypt 和 MySQL 的用户身份验证 API的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn