Nodejs 中使用 mongodb 数据库进行安全身份验证。
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中文网其他相关文章!

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

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

热门文章

热工具

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

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

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

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript不需要安装,因为它已内置于现代浏览器中。你只需文本编辑器和浏览器即可开始使用。1)在浏览器环境中,通过标签嵌入HTML文件中运行。2)在Node.js环境中,下载并安装Node.js后,通过命令行运行JavaScript文件。
