国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁(yè) web前端 js教程 Nodejs 中使用 mongodb 數(shù)據(jù)庫(kù)進(jìn)行安全身份驗(yàn)證。

Nodejs 中使用 mongodb 數(shù)據(jù)庫(kù)進(jìn)行安全身份驗(yàn)證。

Nov 05, 2024 am 11:19 AM

A secure authentication in nodejs with mongodb database.

Node.js 包參考指南

核心依賴

網(wǎng)絡(luò)框架和服務(wù)器

  • 特快 (^4.18.2)
    • Web 應(yīng)用程序框架
    • 處理路由、中間件和 HTTP 請(qǐng)求/響應(yīng)
    • 構(gòu)建 API 和 Web 應(yīng)用程序的核心基礎(chǔ)

數(shù)據(jù)庫(kù)

  • 貓鼬 (^7.0.0)
    • MongoDB 對(duì)象建模工具
    • 提供基于模式的解決方案來(lái)建模應(yīng)用程序數(shù)據(jù)
    • 處理數(shù)據(jù)庫(kù)操作和關(guān)系

安全包

  • jsonwebtoken (^9.0.0)

    • 創(chuàng)建并驗(yàn)證 JSON Web 令牌 (JWT)
    • 用于用戶身份驗(yàn)證和安全信息交換
  • bcryptjs (^2.4.3)

    • 安全地散列和比較密碼
    • 保護(hù)數(shù)據(jù)庫(kù)中的用戶密碼
  • 頭盔 (^6.0.1)

    • 向 HTTP 響應(yīng)添加安全標(biāo)頭
    • 防止常見(jiàn)的網(wǎng)絡(luò)漏洞
    • 設(shè)置各種 HTTP 標(biāo)頭以確保安全
  • cors (^2.8.5)

    • 實(shí)現(xiàn)跨源資源共享
    • 控制哪些域可以訪問(wèn)您的 API
    • 對(duì)于具有獨(dú)立前端/后端的 Web 應(yīng)用程序至關(guān)重要

驗(yàn)證和配置

  • joi (^17.9.0)

    • 數(shù)據(jù)驗(yàn)證庫(kù)
    • 驗(yàn)證請(qǐng)求正文、查詢參數(shù)和其他輸入
    • 確保數(shù)據(jù)完整性和格式
  • dotenv (^16.0.3)

    • 從 .env 文件加載環(huán)境變量
    • 管理配置設(shè)置
    • 確保敏感數(shù)據(jù)的安全

開(kāi)發(fā)依賴

開(kāi)發(fā)工具

  • nodemon (^2.0.22)
    • 監(jiān)控開(kāi)發(fā)過(guò)程中的文件更改
    • 自動(dòng)重啟服務(wù)器
    • 改進(jìn)開(kāi)發(fā)工作流程

使用示例

// 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 項(xiàng)目結(jié)構(gòu)指南

項(xiàng)目結(jié)構(gòu)

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. 初始設(shè)置

包.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. 配置設(shè)置

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. 實(shí)用工具

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. 主要申請(qǐng)文件

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

運(yùn)行應(yīng)用程序

  1. 安裝依賴項(xiàng):
npm install
  1. 在 .env 中設(shè)置環(huán)境變量

  2. 啟動(dòng)開(kāi)發(fā)服務(wù)器:

npm run dev
  1. 用于生產(chǎn):
npm start

測(cè)試 API

使用Postman或curl等工具測(cè)試API端點(diǎn):

# 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"}'

這份結(jié)構(gòu)化指南為 Node.js 和 Mongoose 應(yīng)用程序提供了完整的設(shè)置,并具有適當(dāng)?shù)慕M織、錯(cuò)誤處理和安全功能。每個(gè)文件都有其特定的職責(zé),使代碼庫(kù)可維護(hù)和可擴(kuò)展。

以上是Nodejs 中使用 mongodb 數(shù)據(jù)庫(kù)進(jìn)行安全身份驗(yàn)證。的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門(mén)話題

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語(yǔ)言,各自適用于不同的應(yīng)用場(chǎng)景。Java用于大型企業(yè)和移動(dòng)應(yīng)用開(kāi)發(fā),而JavaScript主要用于網(wǎng)頁(yè)開(kāi)發(fā)。

JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

掌握J(rèn)avaScript評(píng)論:綜合指南 掌握J(rèn)avaScript評(píng)論:綜合指南 Jun 14, 2025 am 12:11 AM

評(píng)論arecrucialinjavascriptformaintainingclarityclarityandfosteringCollaboration.1)heelpindebugging,登機(jī),andOnderStandingCodeeVolution.2)使用林格forquickexexplanations andmentmentsmmentsmmentsmments andmmentsfordeffordEffordEffordEffordEffordEffordEffordEffordEddeScriptions.3)bestcractices.3)bestcracticesincracticesinclud

JavaScript數(shù)據(jù)類(lèi)型:深度潛水 JavaScript數(shù)據(jù)類(lèi)型:深度潛水 Jun 13, 2025 am 12:10 AM

JavaScripthasseveralprimitivedatatypes:Number,String,Boolean,Undefined,Null,Symbol,andBigInt,andnon-primitivetypeslikeObjectandArray.Understandingtheseiscrucialforwritingefficient,bug-freecode:1)Numberusesa64-bitformat,leadingtofloating-pointissuesli

JavaScript與Java:開(kāi)發(fā)人員的全面比較 JavaScript與Java:開(kāi)發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

如何在JS中與日期和時(shí)間合作? 如何在JS中與日期和時(shí)間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時(shí)間處理需注意以下幾點(diǎn):1.創(chuàng)建Date對(duì)象有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時(shí)間信息可用get和set方法,注意月份從0開(kāi)始;3.手動(dòng)格式化日期需拼接字符串,也可使用第三方庫(kù);4.處理時(shí)區(qū)問(wèn)題建議使用支持時(shí)區(qū)的庫(kù),如Luxon。掌握這些要點(diǎn)能有效避免常見(jiàn)錯(cuò)誤。

JavaScript:探索用于高效編碼的數(shù)據(jù)類(lèi)型 JavaScript:探索用于高效編碼的數(shù)據(jù)類(lèi)型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

為什么要將標(biāo)簽放在的底部? 為什么要將標(biāo)簽放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

See all articles