使用 Nodejs、Expressjs 和 Mongodb 的博客 API
介绍
先决条件
介绍
这是一个简单的博客 API。它包含身份验证,因此只有博客所有者才能创建、编辑和删除帖子。它使用 Node、Express 和 MongoDB。
该 API 具有以下端点:
方法 | 端点 | 描述 |
---|---|---|
邮政 | /api/posts | 创建新帖子。需要身份验证。 |
得到 | /api/posts | 获取所有帖子。 |
得到 | /api/posts/:id | 通过 ID 获取单个帖子。 |
放 | /api/posts/:id | 更新帖子。需要身份验证。 |
删除 | /api/posts/:id | 删除帖子。需要身份验证。 |
邮政 | /api/注册 | 注册新用户。 |
邮政 | /api/登录 | 登录用户。 |
邮政 | /api/注销 | 注销用户。需要身份验证。 |
在下一节中,我们将介绍本教程的一些先决条件。
先决条件
完成本教程需要满足以下条件:
-
Nodejs安装在您的系统上。
-
对 JavaScript 和 Nodejs 有深入的了解。
- MongoDB与 MongoDB 数据库建立连接。
设置
让我们开始使用 Node.js 代码。创建一个名为 Blog site API 的文件夹。
然后,在终端中输入npm init -y
创建 package.json 文件。
之后,您必须安装一些软件包才能继续操作。
这些软件包将在整个项目中使用。
使用终端在 api 文件夹中安装 Express、Mongoose、dotenv 和 bcryptjs。
npm i express mongoose dotenv bcryptjs
安装软件包后,创建一个名为.env的文件。之后,启动 MongoDB 并将链接复制到我们的项目。
mongodb+srv://user:password@cluster0.hex8l.mongodb.net/name-database?retryWrites=true&w=majority
MongoDB 地址我们将使用 dotenv 包将其连接到主文件夹。该包帮助我们将机密信息与源代码分离。这在将项目上传到 GitHub 时非常有用。您可能不想与他人共享数据库登录信息,因此您可以分发源代码。如您所见,我需要在项目中隐藏我的密码。
我还安装了bcryptjs
如上所示的软件包。这个软件包使我们能够创建一个密码安全平台,该平台可随计算能力扩展,并始终对每个密码进行加盐处理。
让我们创建一个主文件,并将其命名为 index.js。所有路由和中间件都将在这里组装。在继续操作之前,请将 nodemon 导入到 API 文件夹中。对 index.js 文件中代码的任何更改都会导致 Node 服务器立即重启。
npm i nodemon
初始路线设置
让我们从第一个路由开始,它检查一切是否正常。Node.js Express 包允许您创建路由,这也是大多数互联网的工作方式。大多数后端语言(例如 Node.js 和 Java)都提供了创建与数据库交互的路由的功能。第一个路由不与数据库交互,在通过 GET 请求访问时仅返回文本。
在 API 文件夹中,创建一个 index.js 文件。首先,导入 Express 和 Mongoose 包。接下来,使用 Express 创建一个端口变量,该变量将在指定的端口上运行,如果没有可用端口,则使用端口 5000。
const express = require('express');
const mongoose = require('mongoose');
//App Config
const app = express()
const port = process.env.PORT || 5000
//Middleware
//DB Config
//API Endpoints
//Listener
app.listen(port, () => console.log(`Listening on localhost: ${port}`))
访问数据库和网络
您必须在 MongoDB 中创建一个数据库用户并授予网络访问权限。并使用 dotenv 将其连接到初始路由,因为我们已将链接保存在 .env 文件中。
const dotenv = require("dotenv");
dotenv.config();
//Database Connection
Connect.CONNECTDB(process.env.URL);
数据库模式和路由
我们使用的数据库 MongoDB 采用 JSON 格式存储数据,而不是像 Oracle 等传统数据库那样采用常规的表结构。您需要创建 MongoDB 所需的模式文件。该文件描述了 MongoDB 中字段的存储方式。
首先,创建一个名为 models 的文件夹。在其中创建一个文件,并将其命名为“User.js”。我们将在这里编写身份验证架构。
授权架构
我们将首先为网站上注册的用户开发身份验证方案。用户信息保存在数据库中。这样,当用户稍后返回时,他们只需登录即可,因为服务器会根据保存的信息识别他们。
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
username:{
type: String,
required: true,
unique:true,
min:3,
max:20
},
email:{
type: String,
required: true,
unique:true
},
password:{
type: String,
required: true,
min:3,
max:10
},
},
{timestamps: true}
);
module.exports = mongoose.model("User", UserSchema);
此外,如上面的代码所示,在最后一行,我们导出了代码以便将其导入到路由中。
如您所见,该模式包含将存储在数据库中的详细信息,例如用户名、电子邮件和密码。当用户尝试登录时,服务器将检查该用户是否存在于数据库中,如果用户详细信息在数据库中,则允许该用户登录。
现在让我们创建帖子模式,我们将在其中存储我们想要在帖子中的内容。
在模型文件夹中,该文件夹创建一个名为“Post.js”的文件,我们将在其中编写我们的 Post Schema。
const mongoose = require('mongoose');
const PostSchema = new mongoose.Schema({
desc: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
{timestamps: true}
);
module.exports = mongoose.model('Post', PostSchema);
我们的文章架构包含将存储在数据库中的标题和描述。
现在,该架构用于创建将数据添加到数据库的端点。这里使用了 MVC 模式;这是 Web 应用程序的标准流程。
然后,使用 POST 请求将用户的任何数据发送到数据库。可以使用任何端点。如果您在 Dev.to 上撰写了一篇文章,然后点击 POST 按钮,则一旦发出 POST 请求,您的文章就会保存到 Dev.to 数据库中。GET
端点会检索所有数据库数据。同样,可以指定任何端点。例如,当您浏览 Dev.to 中的帖子时,会向该端点发送 GET 请求,该端点会从 Dev.to 数据库中检索所有帖子。
路线
创建一个名为 routes 的文件夹。我们先从身份验证路由开始。在 routes 文件夹中创建一个名为 Auth.js 的文件,其中包含以下身份验证代码:-
const router = require('express').Router();
const User = require('../models/User');
const bcrypt = require('bcryptjs')
//register endpoint
router.post('/register', async (req,res)=> {
// const confirm = await User.find({Username : req.body.username ,email : req.body.email})
//confirm && res.status(400).json('this user or email exist');
try {
const salt = await bcrypt.genSalt(10);
const hashedPass = await bcrypt.hash(req.body.password, salt);
const savedPost = await new User({
username: req.body.username,
email: req.body.email,
password: hashedPass
})
const resultPost = await savedPost.save();
res.status(200).json(resultPost);
} catch (error) {
res.status(500).json(error);
}
})
//login endpoint
router.post('/login', async (req,res)=>{
try {
const user = await User.findOne({username : req.body.username});
!user && res.status(400).json('wrong user');
const validate = await bcrypt.compare(req.body.password,user.password);
!validate && res.status(400).json('wrong password');
const {password, ...others} = user._doc;
res.status(200).json(others);
} catch (error) {
res.status(500).json(error);
}
})
module.exports = router;
正如您在上面的代码中看到的,我们导入了模式并将使用它来插入和保存详细信息。
向 /register 端点发送 POST 请求。对于 MongoDB,负载位于 req.body.username,password,email 中。然后,使用该New
方法发送用户信息。如果成功,您将获得状态 200;否则,您将获得状态 500。
要从数据库获取数据,
请创建一个指向 /login 的 post 端点。此处使用 findOne() 函数,成功代码为 200(否则,状态码为 500)。
如前所述,我们在代码中使用了 bcryptjs 来保护密码。
我们来看看 Post 路由吧?在 routes 文件夹中创建一个名为“Post.js”的文件。Post 文件的代码如下所示。
const router = require('express').Router();
const Post = require('../models/Post');
//create post
router.post('/', async (req,res)=> {
try {
const savePost = await new Post(req.body);
const savedPost = await savePost.save()
res.status(200).json(savedPost);
} catch (error) {
res.status(500).json(error);
}
})
//update post
router.put('/:id', async (req,res)=> {
try {
const post = await Post.findById(req.params.id);
if(post.userId === req.body.userId) {
await Post.updateOne({$set:req.body});
res.status(200).json('it has been updated);
} else {
res.status(403).json('you can only update your post');
}
} catch (error) {
res.status(500).json(error)
}
})
//delete post
router.delete('/:id', async (req, res)=> {
try {
const post = await Post.findById(req.params.id);
if (post.userId === req.body.userId) {
await Post.delete()
res.status(200).json('the post is deleted)
} else {
res.status(403).json("you can only delete your post")
}
} catch (error) {
res.status(500).json(error)
}
})
//get All posts
router.get('/', async (req,res) => {
try {
const posts = await Post.find();
res.status(200).json(posts);
} catch (error) {
res.status(500).json(error);
}
})
//get one post
router.get('/:id',async(req,res)=> {
try {
const post = await Post.findById(req.params.id);
res.status(200).json(post);
} catch (error) {
res.status(500).json(error);
}
})
module.exports = router;
在上面的代码中,我们创建了帖子,保存了帖子,可以编辑帖子,删除帖子,并且可以检索所有帖子或仅检索一个帖子。
首先,我们使用 方法创建帖子post
并按指示保存。我们使用put
方法编辑帖子,在使用findById
mongoose 包提供的方法找到帖子后,我们使用update
方法更新帖子。
在第三种方法中,我们使用delete
。在其中我们使用 方法找到要删除的帖子findById
,然后使用 delete() 删除帖子。
此外,在代码的最后一行,我们使用路由器导出了代码,并使用第一个 get 仅查找一篇帖子,第二个 get 查找所有帖子。这使我们能够轻松跟踪处理请求并将其发送到主文件索引。让我在下面的屏幕截图中演示一下。
如上图所示,我们现在可以使用该use()
函数将路由作为中间件访问。导入代码后,路由器功能会使其更加便捷。
最后import authroute = require('./routes/Auth');
,如图所示,我们创建了端点/api/blog
和路由器。
别忘了 express。json() 中间件是 express 内置的一个方法,它将传入的请求对象识别为 JSON 对象,因为我们的数据是 JSON 格式的。
感谢您阅读本文。希望您从中有所收获。下一篇文章,我们将学习如何在 Postman 软件中进行测试。
文章来源:https://dev.to/collins87mbathi/blog-site-api-with-authentication-in-node-express-and-mongodb-59h4