我正在使用MEAN堆栈构建应用程序,我对它很新。我目前的问题是我试图将我的冲浪模型引用到Express中的用户模型。我想要它做的只是创建一个新的Surf对象,引用创建它的用户。当我尝试在POST请求上创建新的Surf对象时,我当前的设置会发出错误。顺便说一句,我也使用jsonwebtokens进行身份验证。不确定这与它有什么关系,但只是提到它。任何帮助表示赞赏。
/models/surf.js
// surf.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//SURF SCHEMA
// ============================================
var SurfSchema = new Schema({
title: String,
longitude: Number,
latitude: Number,
comment: String,
created: { type: Date, default: Date.now },
user_id: {type: Schema.ObjectId, ref: 'User'}
});
var Surf = mongoose.model('Surf', SurfSchema);
module.exports = Surf;
/models/user.js
//USER MODEL
// Require packages for User model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt-nodejs');
//USER SCHEMA
// ============================================
var UserSchema = new Schema({
name: String,
username: {type: String, required: true, index: {unique: true}},//No duplicate usernames
password: {type: String, required: true, select: false}//Do not return password
});
//HASH PASSWORD
// ============================================
//Hash password before saving
UserSchema.pre('save', function(next){
var user = this;
//Hash password only if the password has been changed or is new
if(!user.isModified('password')) return next();
//Generate Salt
bcrypt.hash(user.password,null, null, function(err,hash){
if(err) return next(err);
//Change the password to the hash version
user.password = hash;
next();
});
});
//Create method to compare a given password with the database hash
UserSchema.methods.comparePassword = function(password){
var user = this;
return bcrypt.compareSync(password,user.password);
};
//Create User model out of userSchema
var User = mongoose.model('User', UserSchema);
module.exports = User;
/routes/api.js
//api.js
var bodyParser = require('body-parser');
var User = require('../models/user');
var Surf = require('../models/surf');
var jwt = require('jsonwebtoken');
var config = require('../config');
//superSecret secret for creating tokens
var superSecret = config.secret;
//Pass in app and express to use express object for express.Router()
module.exports = function(app, express){
// Instance of express Router
var apiRouter = express.Router();
//API AUTHENTICATE ROUTE
// ====================================================================
//Route for authenticating user at /api/authenticate
apiRouter.post('/authenticate', function(req, res){
//find the user and select username and password explicitly
User.findOne({
username: req.body.username
}).select('name username password').exec(function(err, user){
if(err) throw err;
// no user with that username was found
if(!user){
res.json({success: false, message: 'Authentication failed. User not found'});
}else if (user) {
//check if password is a match
var validPassword = user.comparePassword(req.body.password);
if(!validPassword) {
res.json({success: false, message: 'Authentication failed. Wrong password'});
}else {
//if user is found and password matches
var token = jwt.sign({
name: user.name,
username: user.username
}, superSecret, {
expiresInMinutes: 1440 //Expires in 24 hours
});
//return the information including token as json
res.json({
success: true,
message: 'Here is your token',
token: token
});//End response json
}
}
});
});//End Post authenticate
//TOKEN MIDDLEWARE
// ====================================
//Middleware to use before for all requests(Token varification)
apiRouter.use(function(req,res,next){
//logging
console.log('A visitor has arrived');
//Check Header OR Url parameters OR POST parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
//Decode the token
if(token){
//Verifies secret and checks expiration
jwt.verify(token, superSecret, function(err, decoded){
if(err){
return res.json({success: false, message: 'Failed token authentication'});
}else {
//If token checks out, save the request to be used in other routes
req.decoded = decoded;
next();//User may continue forward if they have a valid token
}
});
}else {
//if there is no token return 403(access forbidden) and an error message
return res.status(403).send({success: false, message: 'No token Provided'});
}
});//End Middleware
//TEST ROUTE
// ====================================
//Test Route
apiRouter.get('/', function(req,res){
res.json({message: "Welcome to the API"});
});
//API ROUTES USERS
// ====================================================================
//routes that end with /users --------------------
apiRouter.route('/users')
//CREATE a user on /api/users
.post(function(req, res){
//creat a new user instance from User model
var user = new User();
//set the users information that comes from requests
user.name = req.body.name;
user.username = req.body.username;
user.password = req.body.password;
//save user and check for errors
user.save(function(err){
if(err){
//A duplicate was entered
if(err.code == 11000){
return res.json({success: false, message: 'A user with that username exists'});
}else {
return res.send(err);
}
}
res.json({message: 'User created!'});
});//End save
})//End Post
//GET all users at /api/users
.get(function(req, res){
User.find(function(err,users){
if(err){
res.send(err);
}
//Return all users
res.json(users);
});
});//End Get
//routes that end with /users:user_id --------------------
apiRouter.route('/users/:user_id')
//GET a single user at /users/:user_id
.get(function(req,res){
User.findById(req.params.user_id, function(err,user){
if(err) res.send(err);
// return the user
res.json(user);
});
})//End Get
//UPDATE the user with this id at /users/:user_id
.put(function(req,res){
//use user model to find the user we want
User.findById(req.params.user_id, function(err,user){
if(err) res.send(err);
//update the users info only if it is new(no blanks)
if(req.body.name) user.name = req.body.name;
if(req.body.username) user.username = req.body.username;
if(req.body.password) user.password = req.body.password;
//save user
user.save(function(err){
if(err) res.send(err);
// return message
res.json({message: 'User has been updated!'});
});//End save
});//End find by id
})//End Post
//DELETE a user with this id at /users/:user_id
.delete(function(req,res){
User.remove({
_id: req.params.user_id
}, function(err, user){
if(err) res. send(err);
res.json({message: 'Succesfully deleted user'});
});
});
//api endpoint to get user information
apiRouter.get('/me', function(req, res){
res.send(req.decoded);
});
//API ROUTES SURF
// ====================================================================
//routes that end with /surf --------------------
apiRouter.route('/surf')
//CREATE a surf on /api/surf
.post(function(req, res){
//create a new instance of the surf model
var surf = new Surf();
User.findOne({username: decoded.username}, function(err, user){
req.user = user;
next()
})
//set the surf information that comes from requests
surf.title = req.body.title;
surf.longitude = req.body.longitude;
surf.latitude = req.body.latitude;
surf.comment = req.body.comment;
surf.user_id = req.user._id;
//save user and check for errors
surf.save(function(err){
if(err)
res.send(err);
res.json({message: 'Surf Session Created!'});
});//End save
})//End Post
//GET all surf sessions at api/surf
.get(function(req, res){
// Use the Surf model to find all surf sessions
Surf.find({ }, function(err, surfSesh) {
if (err)
res.send(err);
res.json(surfSesh);
});
})//
return apiRouter;
};
我试过surf.user_id = req.user._id; 但我不断得到错误 读取属性'_id of undefined'
答案 0 :(得分:0)
在这个其他区块中:
}else {
//If token checks out, save the request to be used in other routes
req.decoded = decoded;
next();//User may continue forward if they have a valid token
}
您有一个已解码的令牌,这意味着您应该有权访问该用户名。您接下来要做的是获取用户模型,并将其设置为req
对象,然后再调用next()
,例如
User.findOne({username: decoded.username}, function(err, user){
req.user = user;
next()
})
--- ---- EDIT
//TOKEN MIDDLEWARE
// ====================================
//Middleware to use before for all requests(Token varification)
apiRouter.use(function(req,res,next){
//logging
console.log('A visitor has arrived');
//Check Header OR Url parameters OR POST parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
//Decode the token
if(token){
//Verifies secret and checks expiration
jwt.verify(token, superSecret, function(err, decoded){
if(err){
return res.json({success: false, message: 'Failed token authentication'});
}else {
//If token checks out, save the request to be used in other routes
req.decoded = decoded;
// GET USER HERE
User.findOne({username: decoded.username}, function(err, user){
req.user = user;
next()
})
}
});
}else {
//if there is no token return 403(access forbidden) and an error message
return res.status(403).send({success: false, message: 'No token Provided'});
}
});//End Middleware