【问题标题】:Trouble saving new post using mongoose and node / express使用猫鼬和节点/快递保存新帖子时遇到问题
【发布时间】:2020-01-23 07:11:24
【问题描述】:

我想使用 Mongoose 和 Node / Express 将新帖子保存到 MongoDB。对我来说,这是使用 Node.js 开始在博客网站上工作的缺失部分。

我分享的代码来自

'routes':posts、verifyToken 和 auth 模型:帖子、用户

当我尝试使用帖子路由发帖时发生错误。

{
    "errors": {
        "owner": {
            "stringValue": "\"{ iat: 1579749217 }\"",
            "kind": "ObjectID",
            "value": {
                "iat": 1579749217
            },
            "path": "owner",
            "reason": {
                "stringValue": "\"{ iat: 1579749217 }\"",
                "kind": "ObjectId",
                "value": {
                    "iat": 1579749217
                },
                "path": "owner",
                "reason": {},
                "message": "Cast to ObjectId failed for value \"{ iat: 1579749217 }\" at path \"owner\"",
                "name": "CastError"
            },
            "message": "Cast to ObjectID failed for value \"{ iat: 1579749217 }\" at path \"owner\"",
            "name": "CastError"
        }
    },
    "_message": "Post validation failed",
    "message": "Post validation failed: owner: Cast to ObjectID failed for value \"{ iat: 1579749217 }\" at path \"owner\"",
    "name": "ValidationError"
}

posts.js

const router = require('express').Router();
const Post = require('../models/Post');
const verify = require('./verifyToken');

router.post('/', verify, async (req, res) => {
    const post = new Post({
        title: "FIRST TITLE",
        desc: "FIRST DESCRIPTION",
        owner: req.user
    })
    try {
        const newPost = await post.save();
        res.status(201).send(newPost);
    } catch(err) {
        res.send(err);
    }
})

module.exports = router;

auth.js

const router = require('express').Router();
const User = require('../models/User');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const {registerValidation, loginValidation} = require('../validation');

router.post('/register', async (req,res) => {
    const {error} = registerValidation(req.body);
    if(error) return res.status(400).send(error.details[0].message);

    const emailExists =  await User.findOne({email: req.body.email});
    if(emailExists) return res.status(400).send('Email already exists!');

    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(req.body.password, salt);

    const user = new User({
        name: req.body.name, email: req.body.email, password: hashedPassword
    })

    try {
        const newUser = await user.save();
        res.json(newUser);
    } catch(err) {
        res.json({message:err})
    }
})

router.post('/login', async (req,res) => {
    const {error} = loginValidation(req.body);
    if(error) return res.status(400).send(error.details[0].message);

    const user = await User.findOne({email: req.body.email});
    if (!user) return res.status(400).send("email does not exist");

    const validPassword = await bcrypt.compare(req.body.password, user.password);
    if(!validPassword) return res.status(400).send("password is incorrect");

    const token = jwt.sign({_id: req.body._id}, process.env.TOKEN_SECRET);
    res.header('auth-token', token).send(token);
})

module.exports = router;

verifyToken.js

const jwt = require('jsonwebtoken');

function tokenAuth (req,res,next){
    const token = req.header('auth-token');
    if (!token) return res.status(401).send("Access Denied!");
    try {
        const verified = jwt.verify(token, process.env.TOKEN_SECRET);
        req.user = verified;
        next();
    } catch(err) {
        res.status(400).send('Invalid_Token');
    }
}

module.exports = tokenAuth;

模型:User.js

const mongoose = require('mongoose');
const Data = require('./Post');

const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        min: 6,
        max: 255
    },
    email: {
        type: String,
        required: true,
        min: 6,
        max: 255
    },
    password: {
        type: String,
        required: true,
        min: 6,
        max: 1024
    },
    date: {
        type: Date,
        default: Date.now
    }
})

module.exports = mongoose.model('User', userSchema);

模型:Post.js

const mongoose = require('mongoose');

const PostSchema = mongoose.Schema({
        title: {
            type: String, 
            required: true,
            max: 40
        },
        desc: {
            type: String,
            required: true,
            max: 100
        },
        owner: {
            type: mongoose.Schema.Types.ObjectId,
            required: true,
            ref: 'User'
        }
})

module.exports = mongoose.model('Post', PostSchema);

我完全迷失了,每个解决方案要么不起作用,要么不适用于我的设置!

【问题讨论】:

  • req.user 不是有效的 mongoDB id.. 打印 req.user 并查看
  • 我希望帖子引用实际用户,这就是我使用它的原因。 req.user 打印上面错误中的数字。

标签: javascript node.js mongodb express mongoose


【解决方案1】:

由于错误状态 "Cast to ObjectId failed for value \"{ iat: 1579749217 }\" at path \"owner\"",您在为所有者键插入帖子时尝试保存的值不是 mongo id。尝试在req.user 添加一个断点或对其进行安慰以检查您在 req.user 中获得的值是多少。

【讨论】:

  • 知道了,我仍然不知道如何让它引用实际用户(所有者),这就是我使用它的原因。 req.user 打印上面错误中的数字。我不希望它是一个随机的帖子,我想稍后使用用户 ID 查询它,因为理论上他是发帖的人
【解决方案2】:

您正在为 verifyToken.js 中的用户分配、解码的 JWT 值,

req.user = verified; 

当您尝试保存用 posts.js 中的代码编写的帖子时,

const post = new Post({
        title: "FIRST TITLE",
        desc: "FIRST DESCRIPTION",
        owner: req.user
    })

您将解码后的值分配给类型为ObjectId 的所有者。请在那里分配一个有效的 ObjectId。 您可以使用

new mongoose.Types.ObjectId();

或从mongoose.Types.ObjectId() 中的解码令牌_id 中传递ID,以构造与User 集合中存在的相同的ObjectId。

【讨论】:

  • 嘿 Shivam,非常感谢 :) 我将 verify._id 传递给帖子所有者部分(不是帖子模型)中的 objectID 参数,但现在我不断得到随机 ID 号,不应该用户只有一个 id?
  • @mobied 是的用户应该具有与在用户模式中创建的相同的 id。您正在使用随机 id jwt.sign({_id: req.body._id}, process.env.TOKEN_SECRET 签署令牌);您需要在此处的代码中在上面的 3 行中通过用户验证后收到的 user._id。
猜你喜欢
  • 2020-02-18
  • 2017-01-29
  • 2016-09-18
  • 2020-02-23
  • 1970-01-01
  • 2021-03-01
  • 2021-04-12
  • 2021-04-11
  • 2014-11-19
相关资源
最近更新 更多