"TypeError: undefined is not a function" for method in schema representing user
"TypeError: undefined is not a function" for method in schema representing user
我正在尝试 'Mean Machine' 书中的练习,创建 API 并验证用户并提供令牌。我在 comparePassword()
上收到 'TypeError: undefined is not a function'。我做错了什么?
这是我的错误。
server.js:69
var validPassword = user.comparePassword(req.body.password);
^
TypeError: undefined is not a function
这里是似乎导致问题的代码(一半):
// more routes for our API will happen here
apiRouter.post('/authenticate', function(req, res){
// find the user
// select the name username 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 matches
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 is right
// create a token
var token = jwt.sign({
name: user.name,
username: user.username
}, superSecret, {
expiresInMinutes: 1440 // expires after 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'enjoy your token!',
token: token
});
}
}
});
});
以上内容与 server.js 文件的其余部分相关联:
// Base Setup
// ======================================
// CALL THE PACKAGES
var express = require('express'); // call express
var app = express(); // define our app using express
var bodyParser = require('body-parser'); // get body-parser
var morgan = require('morgan'); // used to see requests
var mongoose = require('mongoose'); // for working w/ our database
var User = require('./app/models/user');
var port = process.env.PORT || 8080; // Set the port for our app
var jwt = require('jsonwebtoken');
// super secret for creating tokens
var superSecret = 'rockabyezebra';
//APP CONFIGURATION
// Use body-parser so we can grab information from post requests
app.use(bodyParser.urlencoded({extended: true }));
app.use(bodyParser.json());
// configure our app to handle CORS requests
app.use(function(req, res, next){
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET', 'POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, \ Authorization');
next();
});
// log all requests to the console
app.use(morgan('dev'));
// connect to our database (hosted on mongolab.com)
mongoose.connect('mongodb://blah:blahblah@ds031852.mongolab.com:31852/app42');
// ROUTES FOR OUR API
// ================================
var apiRouter = express.Router(); // get an instance of the express Router
// basic route for the homepage
app.get('/', function(req, res){
res.send('Welcome to the home page');
});
// get an instance of the express router
var apiRouter = express.Router();
// more routes for our API will happen here
apiRouter.post('/authenticate', function(req, res){
// find the user
// select the name username 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 matches
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 is right
// create a token
var token = jwt.sign({
name: user.name,
username: user.username
}, superSecret, {
expiresInMinutes: 1440 // expires after 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'enjoy your token!',
token: token
});
}
}
});
});
// middleware to use for all requests
apiRouter.use(function(req, res, next){
// do logging
console.log('Somebody just visited our app');
// we'll add more to the middleware in Chapter 10
// this is where we will authenticate users
next(); // make sure we go to the next routes and don't stop here
});
// test route to make sure everything is working
// accessed at GET http://localhost:8080/api
apiRouter.get('/', function(req, res){
res.json({ message: 'hooray! welcome to our api'});
});
// on routes that end in /users
// ---------------------------------------------------
apiRouter.route('/users')
// create a user (accessed at POST http://localhost:8080/users)
.post(function(req, res){
// create a new instance of the user model
var user = new User();
// set the users information (comes from the request)
user.name = req.body.name;
user.username = req.body.username;
user.password = req.body.password;
// save the user and check for errors
user.save(function (err) {
if (err){
// duplicate entry
if (err.code ==11000)
return res.json({ success: false, message: 'A user with that username already exists. '});
else
return res.send(err);
}
res.json ({ message: 'User created'});
});
})
// get all the users (accessed at GET http://localhost:8080/api/users)
.get(function(req,res) {
User.find(function(err, users) {
if (err) return res.send(err);
// return the users
res.json(users);
});
});
// on routes that end in /users/:user_id
// ----------------------------------------------------
apiRouter.route('/users/:user_id')
// get the user with that id
.get(function(req, res) {
User.findById(req.params.user_id, function(err, user) {
if (err) return res.send(err);
// return that user
res.json(user);
});
})
// update the user with this id
.put(function(req, res){
User.findById(req.params.user_id, function(err, user) {
if (err) return res.send(err);
// set the new user information if it exists in the request
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 the user
user.save(function(err){
if (err) return res.send(err);
// return a message
res.json({ message: 'user updated'});
});
});
})
.delete(function(req, res){
User.remove({
_id: req.params.user_id
}, function(err, user) {
if (err) res.send(err);
res.json({ message: 'Successfully deleted'});
});
});
// REGISTER OUR ROUTES ----------------------------------
// all of our routes will be prefixed with /api
app.use('/api', apiRouter);
// START THE SERVER
// ================================
app.listen(port);
console.log('rockin\' on port ' + port + ' y\'all');
我假设您正在使用 mongoose 模块处理您的数据。看起来您从未在 UserSchema
中定义方法 comparePassword
(User
模型来自哪里)。您可以像这样在模式中定义方法。文档 here:
var AnimalSchema = new Schema({
name: String,
type: String
});
AnimalSchema.methods.findSimilarType = function findSimilarType(cb) {
return this.model('Animal').find({
type: this.type
}, cb);
};
// Now when we have an instance of Animal we can call our // findSimilarType method and find all animals with a matching type.
var Animal = mongoose.model('Animal', AnimalSchema);
var dog = new Animal({
name: 'Rover',
type: 'dog'
});
dog.findSimilarType(function(err, dogs) {
if (err) return ...
dogs.forEach(..);
})
我正在尝试 'Mean Machine' 书中的练习,创建 API 并验证用户并提供令牌。我在 comparePassword()
上收到 'TypeError: undefined is not a function'。我做错了什么?
这是我的错误。
server.js:69
var validPassword = user.comparePassword(req.body.password);
^
TypeError: undefined is not a function
这里是似乎导致问题的代码(一半):
// more routes for our API will happen here
apiRouter.post('/authenticate', function(req, res){
// find the user
// select the name username 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 matches
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 is right
// create a token
var token = jwt.sign({
name: user.name,
username: user.username
}, superSecret, {
expiresInMinutes: 1440 // expires after 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'enjoy your token!',
token: token
});
}
}
});
});
以上内容与 server.js 文件的其余部分相关联:
// Base Setup
// ======================================
// CALL THE PACKAGES
var express = require('express'); // call express
var app = express(); // define our app using express
var bodyParser = require('body-parser'); // get body-parser
var morgan = require('morgan'); // used to see requests
var mongoose = require('mongoose'); // for working w/ our database
var User = require('./app/models/user');
var port = process.env.PORT || 8080; // Set the port for our app
var jwt = require('jsonwebtoken');
// super secret for creating tokens
var superSecret = 'rockabyezebra';
//APP CONFIGURATION
// Use body-parser so we can grab information from post requests
app.use(bodyParser.urlencoded({extended: true }));
app.use(bodyParser.json());
// configure our app to handle CORS requests
app.use(function(req, res, next){
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET', 'POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, \ Authorization');
next();
});
// log all requests to the console
app.use(morgan('dev'));
// connect to our database (hosted on mongolab.com)
mongoose.connect('mongodb://blah:blahblah@ds031852.mongolab.com:31852/app42');
// ROUTES FOR OUR API
// ================================
var apiRouter = express.Router(); // get an instance of the express Router
// basic route for the homepage
app.get('/', function(req, res){
res.send('Welcome to the home page');
});
// get an instance of the express router
var apiRouter = express.Router();
// more routes for our API will happen here
apiRouter.post('/authenticate', function(req, res){
// find the user
// select the name username 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 matches
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 is right
// create a token
var token = jwt.sign({
name: user.name,
username: user.username
}, superSecret, {
expiresInMinutes: 1440 // expires after 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'enjoy your token!',
token: token
});
}
}
});
});
// middleware to use for all requests
apiRouter.use(function(req, res, next){
// do logging
console.log('Somebody just visited our app');
// we'll add more to the middleware in Chapter 10
// this is where we will authenticate users
next(); // make sure we go to the next routes and don't stop here
});
// test route to make sure everything is working
// accessed at GET http://localhost:8080/api
apiRouter.get('/', function(req, res){
res.json({ message: 'hooray! welcome to our api'});
});
// on routes that end in /users
// ---------------------------------------------------
apiRouter.route('/users')
// create a user (accessed at POST http://localhost:8080/users)
.post(function(req, res){
// create a new instance of the user model
var user = new User();
// set the users information (comes from the request)
user.name = req.body.name;
user.username = req.body.username;
user.password = req.body.password;
// save the user and check for errors
user.save(function (err) {
if (err){
// duplicate entry
if (err.code ==11000)
return res.json({ success: false, message: 'A user with that username already exists. '});
else
return res.send(err);
}
res.json ({ message: 'User created'});
});
})
// get all the users (accessed at GET http://localhost:8080/api/users)
.get(function(req,res) {
User.find(function(err, users) {
if (err) return res.send(err);
// return the users
res.json(users);
});
});
// on routes that end in /users/:user_id
// ----------------------------------------------------
apiRouter.route('/users/:user_id')
// get the user with that id
.get(function(req, res) {
User.findById(req.params.user_id, function(err, user) {
if (err) return res.send(err);
// return that user
res.json(user);
});
})
// update the user with this id
.put(function(req, res){
User.findById(req.params.user_id, function(err, user) {
if (err) return res.send(err);
// set the new user information if it exists in the request
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 the user
user.save(function(err){
if (err) return res.send(err);
// return a message
res.json({ message: 'user updated'});
});
});
})
.delete(function(req, res){
User.remove({
_id: req.params.user_id
}, function(err, user) {
if (err) res.send(err);
res.json({ message: 'Successfully deleted'});
});
});
// REGISTER OUR ROUTES ----------------------------------
// all of our routes will be prefixed with /api
app.use('/api', apiRouter);
// START THE SERVER
// ================================
app.listen(port);
console.log('rockin\' on port ' + port + ' y\'all');
我假设您正在使用 mongoose 模块处理您的数据。看起来您从未在 UserSchema
中定义方法 comparePassword
(User
模型来自哪里)。您可以像这样在模式中定义方法。文档 here:
var AnimalSchema = new Schema({
name: String,
type: String
});
AnimalSchema.methods.findSimilarType = function findSimilarType(cb) {
return this.model('Animal').find({
type: this.type
}, cb);
};
// Now when we have an instance of Animal we can call our // findSimilarType method and find all animals with a matching type.
var Animal = mongoose.model('Animal', AnimalSchema);
var dog = new Animal({
name: 'Rover',
type: 'dog'
});
dog.findSimilarType(function(err, dogs) {
if (err) return ...
dogs.forEach(..);
})