我的代码在最初之前可以工作,但我不知道为什么它停止工作并给我这个错误:
MongooseError: Operation `users.findOne()` buffering timed out after 10000ms
at Timeout.<anonymous> (/Users/nishant/Desktop/Yourfolio/backend/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:184:20)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7)
我正在尝试通过使用 JWT 登录来验证用户身份。我的客户端运行良好,但在我的后端出现此错误。我的后端代码:
import neuron from '@yummyweb/neuronjs'
import bodyParser from 'body-parser'
import cors from 'cors'
import mongoose from 'mongoose'
import emailValidator from 'email-validator'
import passwordValidator from 'password-validator'
import User from './models/User.js'
import Portfolio from './models/Portfolio.js'
import bcrypt from 'bcryptjs'
import jwt from 'jsonwebtoken'
import auth from './utils/auth.js'
// Dot env
import dotenv from 'dotenv'
dotenv.config()
// Custom Password Specifications
// Username Schema
const usernameSchema = new passwordValidator()
usernameSchema.is().min(3).is().max(18).is().not().spaces()
// Password Schema
const passwordSchema = new passwordValidator()
passwordSchema.is().min(8).is().max(100).has().uppercase().has().lowercase().has().digits().is().not().spaces()
const PORT = process.env.PORT || 5000
const neuronjs = neuron()
// Middleware
neuronjs.use(bodyParser())
neuronjs.use(cors())
// Mongoose Connection
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true }, () => console.log("MongoDB Connected"))
// API Routes
neuronjs.POST('/api/auth/signup', async (req, res) => {
const { username, email, password, passwordConfirmation } = req.body
// Validation: all fields are filled
if (!username || !email || !password || !passwordConfirmation) {
return res.status(400).json({
"error": "true",
"for": "fields",
"msg": "fill all the fields"
})
}
// Validation: username is valid
if (usernameSchema.validate(username, { list: true }).length !== 0) {
return res.status(400).json({
"error": "true",
"for": "username",
"method_fail": usernameSchema.validate(username, { list: true }),
"msg": "username is invalid"
})
}
// Validation: email is valid
if (!emailValidator.validate(email)) {
return res.status(400).json({
"error": "true",
"for": "email",
"msg": "email is invalid"
})
}
// Validation: password is valid
if (passwordSchema.validate(password, { list: true }).length !== 0) {
return res.status(400).json({
"error": "true",
"for": "password",
"method_fail": passwordSchema.validate(password, { list: true }),
"msg": "password is invalid"
})
}
// Validation: password is confirmed
if (password !== passwordConfirmation) {
return res.status(400).json({
"error": "true",
"for": "confirmation",
"msg": "confirmation password needs to match password"
})
}
// Check for existing user with email
const existingUserWithEmail = await User.findOne({ email })
if (existingUserWithEmail)
return res.status(400).json({ "error": "true", "msg": "a user already exists with this email" })
// Check for existing user with username
const existingUserWithUsername = await User.findOne({ username })
if (existingUserWithUsername)
return res.status(400).json({ "error": "true", "msg": "a user already exists with this username" })
// Generating salt
const salt = bcrypt.genSalt()
.then(salt => {
// Hashing password with bcrypt
const hashedPassword = bcrypt.hash(password, salt)
.then(hash => {
const newUser = new User({
username,
email,
password: hash
})
// Saving the user
newUser.save()
.then(savedUser => {
const newPortfolio = new Portfolio({
user: savedUser._id,
description: "",
socialMediaHandles: {
github: savedUser.username,
dribbble: savedUser.username,
twitter: savedUser.username,
devto: savedUser.username,
linkedin: savedUser.username,
}
})
// Save the portfolio
newPortfolio.save()
// Return the status code and the json
return res.status(200).json({
savedUser
})
})
.catch(err => console.log(err))
})
.catch(err => console.log(err))
})
.catch(err => console.log(err))
})
neuronjs.POST('/api/auth/login', async (req, res) => {
try {
const { username, password } = req.body
// Validate
if (!username || !password) {
return res.status(400).json({ "error": "true", "msg": "fill all the fields", "for": "fields", })
}
const user = await User.findOne({ username })
if (!user) {
return res.status(400).json({ "error": "true", "msg": "no account is registered with this username", "for": "username" })
}
// Compare hashed password with plain text password
const match = await bcrypt.compare(password, user.password)
if (!match) {
return res.status(400).json({ "error": "true", "msg": "invalid credentials", "for": "password" })
}
// Create JWT token
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET)
return res.json({ token, user: { "id": user._id, "username": user.username, "email": user.email } })
}
catch (e) {
console.log(e)
}
})
// Delete a user and their portfolio
neuronjs.DELETE("/api/users/delete", async (req, res) => {
auth(req, res)
const deletedPortfolio = await Portfolio.findOneAndDelete({ user: req.user })
const deletedUser = await User.findByIdAndDelete(req.user)
res.json(deletedUser)
})
neuronjs.POST("/api/isTokenValid", async (req, res) => {
const token = req.headers["x-auth-token"]
if (!token) return res.json(false)
const verifiedToken = jwt.verify(token, process.env.JWT_SECRET)
if (!verifiedToken) return res.json(false)
const user = await User.findById(verifiedToken.id)
if (!user) return res.json(false)
return res.json(true)
})
// Getting one user
neuronjs.GET("/api/users/user", async (req, res) => {
auth(req, res)
const user = await User.findById(req.user)
res.json({
"username": user.username,
"email": user.email,
"id": user._id
})
})
// Getting the porfolio based on username
neuronjs.GET("/api/portfolio/:username", async (req, res) => {
try {
const existingUser = await User.findOne({ username: req.params.username })
// User exists
if (existingUser) {
const userPortfolio = await Portfolio.findOne({ user: existingUser._id })
return res.status(200).json(userPortfolio)
}
// User does not exist
else return res.status(400).json({ "error": "true", "msg": "user does not exist" })
}
catch (e) {
console.log(e)
return res.status(400).json({ "error": "true", "msg": "user does not exist" })
}
})
// Update Portfolio info
neuronjs.POST("/api/portfolio/update", async (req, res) => {
auth(req, res)
// Find the portfolio
const portfolio = await Portfolio.findOne({ user: req.user })
// Then, update the portfolio
if (portfolio) {
// Call the update method
const updatedPortfolio = await portfolio.updateOne({
user: req.user,
description: req.body.description,
socialMediaHandles: req.body.socialMediaHandles,
greetingText: req.body.greetingText,
navColor: req.body.navColor,
font: req.body.font,
backgroundColor: req.body.backgroundColor,
rssFeed: req.body.rssFeed,
displayName: req.body.displayName,
layout: req.body.layout,
occupation: req.body.occupation
})
return res.status(200).json(portfolio)
}
})
neuronjs.listen(PORT, () => console.log("Server is running on port " + PORT))
auth.js 文件功能:
import jwt from 'jsonwebtoken'
const auth = (req, res) => {
const token = req.headers["x-auth-token"]
if (!token)
return res.status(401).json({ "error": "true", "msg": "no authentication token" })
const verifiedToken = jwt.verify(token, process.env.JWT_SECRET)
if (!verifiedToken)
return res.status(401).json({ "error": "true", "msg": "token failed" })
req.user = verifiedToken.id
}
export default auth
非常感谢任何帮助,我已经尝试了一些解决方案,例如删除 node_modules 并重新安装 mongoose。
答案 0 :(得分:10)
根据我的经验,当您的数据库未连接时会发生这种情况,请尝试查看以下内容 -
mongoose.connect(...)
代码是否正在加载。我在从终端运行 node index.js
时遇到了这个问题,而 mongoose 连接代码在不同的文件中。在 index.js 中需要那个猫鼬代码后,它又开始工作了。
答案 1 :(得分:7)
根据此链接中的文档:https://mongoosejs.com/docs/connections.html#buffering
<块引用>Mongoose 让您可以立即开始使用您的模型,而无需等待 mongoose 与 MongoDB 建立连接。
那是因为猫鼬在内部缓冲模型函数调用。这 缓冲很方便,但也是一个常见的混淆源。 如果您使用模型,Mongoose 默认不会抛出任何错误 无需连接。
TL;DR:
您的模型在建立连接之前被调用。您需要将 async/await 与 connect() 或 createConnection() 一起使用;或使用 .then(),因为这些函数现在从 Mongoose 5 返回承诺。
答案 2 :(得分:2)
我遇到过很多次了;特别是当我升级了需要猫鼬的嵌套依赖项时。这对我来说总是有用的。
rm -rf node_modules
rm package-lock.json
npm install --package-lock-only
npm install
答案 3 :(得分:1)
创建集群后点击连接并添加您的IP或在MongoDB Atlas中添加另一个IP
答案 4 :(得分:1)
我的代码在一台 PC 上运行正常,但在另一台 PC 上我遇到了同样的错误。我有 https://www.mongodb.com/ 的 MongoDB 免费托管。
我通过将我当前的 IP 添加到托管服务器中的 Security - Network Access - IP Access List
来修复它。
答案 5 :(得分:0)
mongoose.connect('mongodb://localhost/myapp', {useNewUrlParser: true});
只需在连接文件中添加 {useNewUrlParser: true}
。
答案 6 :(得分:0)
显示此错误 [user.findOne()
] 是因为您的 config
软件包版本已自动更新。
在终端中输入以下内容:
npm i -E config@3.3.1
或
yarn add -E config@3.3.1
答案 7 :(得分:0)
我遇到了同样的问题。就我而言,我将 mongoose.connect 语句保存在不同的文件中,但在编写 require 语句时忘记调用它。
require(./services/mongoose);
我已经在我的 index.js 文件中完成了这个并将其更改为这个
require(./services/mongoose)();
答案 8 :(得分:-1)
我的问题从那以后就解决了,我的 mongo db atlas 中已经有一个集合,我所要做的就是清除它并发送另一个帖子请求以使其工作。