Node.js 包参考指南
核心依赖
网络框架和服务器
-
特快 (^4.18.2)
- Web 应用程序框架
- 处理路由、中间件和 HTTP 请求/响应
- 构建 API 和 Web 应用程序的核心基础
数据库
-
猫鼬 (^7.0.0)
- MongoDB 对象建模工具
- 提供基于模式的解决方案来建模应用程序数据
- 处理数据库操作和关系
安全包
-
jsonwebtoken (^9.0.0)
- 创建并验证 JSON Web 令牌 (JWT)
- 用于用户身份验证和安全信息交换
-
bcryptjs (^2.4.3)
- 安全地散列和比较密码
- 保护数据库中的用户密码
-
头盔 (^6.0.1)
- 向 HTTP 响应添加安全标头
- 防止常见的网络漏洞
- 设置各种 HTTP 标头以确保安全
-
cors (^2.8.5)
- 实现跨源资源共享
- 控制哪些域可以访问您的 API
- 对于具有独立前端/后端的 Web 应用程序至关重要
验证和配置
-
joi (^17.9.0)
- 数据验证库
- 验证请求正文、查询参数和其他输入
- 确保数据完整性和格式
-
dotenv (^16.0.3)
- 从 .env 文件加载环境变量
- 管理配置设置
- 确保敏感数据的安全
开发依赖
开发工具
-
nodemon (^2.0.22)
- 监控开发过程中的文件更改
- 自动重启服务器
- 改进开发工作流程
使用示例
// Express server setup const express = require('express'); const app = express(); // Security middleware const helmet = require('helmet'); const cors = require('cors'); app.use(helmet()); app.use(cors()); // Environment variables require('dotenv').config(); // Database connection const mongoose = require('mongoose'); mongoose.connect(process.env.MONGODB_URI); // Validation example const Joi = require('joi'); const schema = Joi.object({ email: Joi.string().email().required() }); // Password hashing const bcrypt = require('bcryptjs'); const hashedPassword = await bcrypt.hash('password', 10); // JWT authentication const jwt = require('jsonwebtoken'); const token = jwt.sign({userId: 123}, process.env.JWT_SECRET);
完整的 Node.js 和 Mongoose 项目结构指南
项目结构
project-root/ ├── src/ │ ├── config/ │ │ ├── database.js │ │ └── config.js │ ├── models/ │ │ ├── user.model.js │ │ └── product.model.js │ ├── controllers/ │ │ ├── user.controller.js │ │ └── product.controller.js │ ├── routes/ │ │ ├── user.routes.js │ │ └── product.routes.js │ ├── middleware/ │ │ ├── auth.middleware.js │ │ └── error.middleware.js │ ├── utils/ │ │ ├── logger.js │ │ └── validators.js │ └── app.js ├── .env ├── .gitignore └── package.json
1. 初始设置
包.json
{ "name": "node-mongoose-project", "version": "1.0.0", "main": "src/app.js", "scripts": { "start": "node src/app.js", "dev": "nodemon src/app.js" }, "dependencies": { "express": "^4.18.2", "mongoose": "^7.0.0", "dotenv": "^16.0.3", "joi": "^17.9.0", "jsonwebtoken": "^9.0.0", "bcryptjs": "^2.4.3", "cors": "^2.8.5", "helmet": "^6.0.1" }, "devDependencies": { "nodemon": "^2.0.22" } }
.env
PORT=3000 MONGODB_URI=mongodb://localhost:27017/your-database JWT_SECRET=your-secret-key NODE_ENV=development
.gitignore
node_modules/ .env logs/ *.log
2. 配置设置
src/config/config.js
require('dotenv').config(); module.exports = { port: process.env.PORT || 3000, mongoUri: process.env.MONGODB_URI, jwtSecret: process.env.JWT_SECRET, nodeEnv: process.env.NODE_ENV || 'development', jwtExpiresIn: '1d' };
src/config/database.js
const mongoose = require('mongoose'); const config = require('./config'); const logger = require('../utils/logger'); const connectDB = async () => { try { await mongoose.connect(config.mongoUri, { useNewUrlParser: true, useUnifiedTopology: true }); logger.info('MongoDB connected successfully'); } catch (error) { logger.error('MongoDB connection error:', error); process.exit(1); } }; module.exports = connectDB;
3. 模型定义
src/models/user.model.js
const mongoose = require('mongoose'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const config = require('../config/config'); const userSchema = new mongoose.Schema({ name: { type: String, required: [true, 'Name is required'], trim: true, minlength: 3, maxlength: 50 }, email: { type: String, required: [true, 'Email is required'], unique: true, lowercase: true, trim: true }, password: { type: String, required: [true, 'Password is required'], minlength: 6, select: false }, role: { type: String, enum: ['user', 'admin'], default: 'user' } }, { timestamps: true }); // Pre-save middleware to hash password userSchema.pre('save', async function(next) { if (!this.isModified('password')) return next(); this.password = await bcrypt.hash(this.password, 12); next(); }); // Instance methods userSchema.methods.generateAuthToken = function() { return jwt.sign( { id: this._id, role: this.role }, config.jwtSecret, { expiresIn: config.jwtExpiresIn } ); }; userSchema.methods.comparePassword = async function(candidatePassword) { return await bcrypt.compare(candidatePassword, this.password); }; const User = mongoose.model('User', userSchema); module.exports = User;
src/models/product.model.js
const mongoose = require('mongoose'); const productSchema = new mongoose.Schema({ name: { type: String, required: true, trim: true }, price: { type: Number, required: true, min: 0 }, description: String, category: { type: String, required: true }, createdBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true } }, { timestamps: true }); const Product = mongoose.model('Product', productSchema); module.exports = Product;
4. 控制器
src/controllers/user.controller.js
const User = require('../models/user.model'); const { validateUser } = require('../utils/validators'); const logger = require('../utils/logger'); exports.register = async (req, res) => { try { const { error } = validateUser(req.body); if (error) return res.status(400).json({ error: error.details[0].message }); const user = await User.create(req.body); const token = user.generateAuthToken(); res.status(201).json({ status: 'success', token, data: { user } }); } catch (error) { logger.error('Registration error:', error); res.status(400).json({ status: 'fail', message: error.message }); } }; exports.login = async (req, res) => { try { const { email, password } = req.body; const user = await User.findOne({ email }).select('+password'); if (!user || !(await user.comparePassword(password))) { return res.status(401).json({ status: 'fail', message: 'Invalid email or password' }); } const token = user.generateAuthToken(); res.json({ status: 'success', token }); } catch (error) { logger.error('Login error:', error); res.status(400).json({ status: 'fail', message: error.message }); } };
5. 路线
src/routes/user.routes.js
const express = require('express'); const router = express.Router(); const userController = require('../controllers/user.controller'); const auth = require('../middleware/auth.middleware'); router.post('/register', userController.register); router.post('/login', userController.login); router.get('/profile', auth, userController.getProfile); module.exports = router;
6. 中间件
src/middleware/auth.middleware.js
const jwt = require('jsonwebtoken'); const config = require('../config/config'); const User = require('../models/user.model'); module.exports = async (req, res, next) => { try { const token = req.headers.authorization?.replace('Bearer ', ''); if (!token) { return res.status(401).json({ status: 'fail', message: 'No token provided' }); } const decoded = jwt.verify(token, config.jwtSecret); const user = await User.findById(decoded.id); if (!user) { return res.status(401).json({ status: 'fail', message: 'User not found' }); } req.user = user; next(); } catch (error) { res.status(401).json({ status: 'fail', message: 'Invalid token' }); } };
src/middleware/error.middleware.js
const logger = require('../utils/logger'); module.exports = (err, req, res, next) => { logger.error(err.stack); if (err.name === 'ValidationError') { return res.status(400).json({ status: 'fail', message: err.message }); } if (err.code === 11000) { return res.status(400).json({ status: 'fail', message: 'Duplicate field value' }); } res.status(err.status || 500).json({ status: 'error', message: err.message || 'Internal server error' }); };
7. 实用工具
src/utils/logger.js
const winston = require('winston'); const config = require('../config/config'); const logger = winston.createLogger({ level: config.nodeEnv === 'development' ? 'debug' : 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), transports: [ new winston.transports.File({ filename: 'logs/error.log', level: 'error' }), new winston.transports.File({ filename: 'logs/combined.log' }) ] }); if (config.nodeEnv === 'development') { logger.add(new winston.transports.Console({ format: winston.format.simple() })); } module.exports = logger;
src/utils/validators.js
const Joi = require('joi'); exports.validateUser = (user) => { const schema = Joi.object({ name: Joi.string().min(3).max(50).required(), email: Joi.string().email().required(), password: Joi.string().min(6).required(), role: Joi.string().valid('user', 'admin') }); return schema.validate(user); }; exports.validateProduct = (product) => { const schema = Joi.object({ name: Joi.string().required(), price: Joi.number().min(0).required(), description: Joi.string(), category: Joi.string().required() }); return schema.validate(product); };
8. 主要申请文件
src/app.js
const express = require('express'); const cors = require('cors'); const helmet = require('helmet'); const config = require('./config/config'); const connectDB = require('./config/database'); const errorMiddleware = require('./middleware/error.middleware'); const userRoutes = require('./routes/user.routes'); const productRoutes = require('./routes/product.routes'); const logger = require('./utils/logger'); // Initialize express app const app = express(); // Connect to MongoDB connectDB(); // Middleware app.use(helmet()); app.use(cors()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Routes app.use('/api/users', userRoutes); app.use('/api/products', productRoutes); // Error handling app.use(errorMiddleware); // Start server app.listen(config.port, () => { logger.info(`Server running in ${config.nodeEnv} mode on port ${config.port}`); }); // Handle unhandled promise rejections process.on('unhandledRejection', (err) => { logger.error('UNHANDLED REJECTION! Shutting down...'); logger.error(err.name, err.message); process.exit(1); });
运行应用程序
- 安装依赖项:
npm install
在 .env 中设置环境变量
启动开发服务器:
npm run dev
- 用于生产:
npm start
测试 API
使用Postman或curl等工具测试API端点:
# Register a new user curl -X POST http://localhost:3000/api/users/register \ -H "Content-Type: application/json" \ -d '{"name": "John Doe", "email": "john@example.com", "password": "password123"}' # Login curl -X POST http://localhost:3000/api/users/login \ -H "Content-Type: application/json" \ -d '{"email": "john@example.com", "password": "password123"}'
这份结构化指南为 Node.js 和 Mongoose 应用程序提供了完整的设置,并具有适当的组织、错误处理和安全功能。每个文件都有其特定的职责,使代码库可维护和可扩展。
以上是Nodejs 中使用 mongodb 数据库进行安全身份验证。的详细内容。更多信息请关注PHP中文网其他相关文章!

Python和JavaScript的主要区别在于类型系统和应用场景。1.Python使用动态类型,适合科学计算和数据分析。2.JavaScript采用弱类型,广泛用于前端和全栈开发。两者在异步编程和性能优化上各有优势,选择时应根据项目需求决定。

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript开发工具