Koa作为一个轻量级、灵活且强大的Node.js框架,与MySQL这一广泛使用的关系型数据库管理系统相结合,能够很好地满足这一需求
本文将详细介绍如何使用Koa和MySQL来实现一个用户登录系统,从项目初始化、数据库设计、API接口开发到安全性考量,全方位覆盖
一、项目初始化 首先,我们需要初始化一个新的Node.js项目,并安装必要的依赖包
1.初始化项目 bash mkdir koa-mysql-login cd koa-mysql-login npm init -y 2.安装依赖 bash npm install koa koa-router koa-bodyparser mysql2 bcryptjs jsonwebtoken -koa:Koa框架核心
-koa-router:用于处理路由
-koa-bodyparser:解析请求体中的JSON数据
-mysql2:MySQL客户端库
-bcryptjs:用于密码哈希处理
-jsonwebtoken:用于生成和验证JWT(JSON Web Tokens)
二、数据库设计与配置 接下来,我们需要设计数据库表结构,并配置MySQL连接
1.设计数据库表 假设我们有一个名为`users`的表,用于存储用户信息
表结构如下: sql CREATE TABLE users( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); 2.配置MySQL连接 在项目根目录下创建一个`db.js`文件,用于配置MySQL连接: javascript const mysql = require(mysql2/promise); const pool = mysql.createPool({ host: localhost, user: root, password: your_password, database: your_database }); module.exports = pool.promise(); 三、API接口开发 接下来,我们将开发用户注册、登录以及验证JWT的API接口
1.创建Koa应用 在项目根目录下创建一个`app.js`文件,作为Koa应用的入口: javascript const Koa = require(koa); const Router = require(koa-router); const bodyParser = require(koa-bodyparser); const jwt = require(jsonwebtoken); const bcrypt = require(bcryptjs); const pool = require(./db); const app = new Koa(); const router = new Router(); // JWT密钥 const JWT_SECRET = your_jwt_secret; // 中间件 app.use(bodyParser()); // 用户注册接口 router.post(/register, async(ctx) =>{ const{ username, password} = ctx.request.body; if(!username ||!password){ ctx.status =400; ctx.body ={ message: Username and password are required}; return; } try{ const hashedPassword = await bcrypt.hash(password,10); const【result】 = await pool.execute(INSERT INTO users(username, password) VALUES(?, ?),【username, hashedPassword】); ctx.status =201; ctx.body ={ message: User registered successfully, userId: result.insertId}; } catch(error){ if(error.code === ER_DUP_ENTRY){ ctx.status =400; ctx.body ={ message: Username already exists}; } else{ ctx.status =500; ctx.body ={ message: Internal server error}; } } }); // 用户登录接口 router.post(/login, async(ctx) =>{ const{ username, password} = ctx.request.body; if(!username ||!password){ ctx.status =400; ctx.body ={ message: Username and password are required}; return; } try{ const【rows】 = await pool.execute(SELECT - FROM users WHERE username = ?,【username】); const user = rows【0】; if(!user ||!(await bcrypt.compare(password, user.password))){ ctx.status =401; ctx.body ={ message: Invalid username or password}; return; } const token = jwt.sign({ userId: user.id}, JWT_SECRET,{ expiresIn: 1h}); ctx.status =200; ctx.body ={ message: Login successful, token}; } catch(error){ ctx.status =500; ctx.body ={ message: Internal server error}; } }); // 受保护的路由中间件 const authenticateJWT = async(ctx, next) =>{ const token = ctx.request.headers.authorization; if(!token){ ctx.status =401; ctx.body ={ message: Authorization header is missing}; return; } try{ const decoded = jwt.verify(token.split( )【1】, JWT_SECRET); ctx.state.user = decoded; await next(); } catch(error){ ctx.status =401; ctx.body ={ message: Invalid token}; } }; // 受保护的路由示例 router.get(/protected, authenticateJWT, async(ctx) =>{ ctx.status =200; ctx.body ={ message: This is a protected route, userId: ctx.state.user.userId}; }); // 使用路由 app.use(router.routes()).use(router.allowedMethods()); // 启动服务器 const PORT = process.e