我想要完成的是在用户发送消息时在数据库中编写消息。我正在使用带角度cli的MEAN堆栈。
我收到的错误是:
TypeError: Cannot read property '_id' of undefined
at JwtStrategy._verify (/Volumes/SSD/Documents/WebProjects/MEANTest/config/passport.js:11:38)
at /Volumes/SSD/Documents/WebProjects/MEANTest/node_modules/passport-jwt/lib/strategy.js:110:26
at /Volumes/SSD/Documents/WebProjects/MEANTest/node_modules/jsonwebtoken/verify.js:27:18
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
以下是我使用的每一段代码,看看有人能弄明白我做错了什么。
Express位于' / users'
的节点router.post('/newmessages', passport.authenticate('jwt', {session: false}), function(req, res, next){
var msgID = getMessageID(req.body.user.username);
let newMessage = Message({
createdBy:req.body.message.createdBy,
recipients:req.body.message.recipients,
dateCreated:getTodayDate(),
subject:req.body.message.subject,
message:req.body.message.message,
read: false,
previousMessage:req.body.message.previousMessage,
nextMessage:req.body.message.nextMessage,
messageID:msgID
});
console.log(newMessage);
Message.checkMessageID(newMessage, function(err, isFound){
if(err) throw err;
if(isFound)
{
newMessage.messageID = getMessageID(req.body.username);
}
else
{
Message.createMessage(newMessage, function(err, isCreated){
if(err) throw err;
if(isCreated)
{
var token = jwt.sign(req.body, config.secret, {
expiresIn: 604800 // A week worth of seconds
});
res.json({
success: true,
token: "JWT " + token,
user: {
id: req.body._id,
name: req.body.name,
username: req.body.username,
email: req.body.email
},
msg: "Your password has been changed."
});
}
else
{
var token = jwt.sign(req.body, config.secret, {
expiresIn: 604800 // A week worth of seconds
});
res.json({
success: true,
token: "JWT " + token,
user: {
id: req.body._id,
name: req.body.name,
username: req.body.username,
email: req.body.email
},
msg: "Your password has been changed."
});
}
});
}
});
});
PassportJS
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var User = require('../models/user');
var config = require('./database');
module.exports = function (passport){
let opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
opts.secretOrKey = config.secret;
passport.use(new JwtStrategy(opts, function(jwt_payload, done){
User.getUserByID(jwt_payload._doc._id, function(err, user){
if(err) {
return done(err, false);
}
if(user){
return done(null, user);
}
else{
return done(null, false);
}
});
}));
};
Mongoose架构和代码:
var mongoose = require('mongoose');
var config = require('../config/messages');
// Message Schema
var messageSchema = mongoose.Schema({
createdBy: {
type: String,
required: true
},
recipients:{
type: String,
required: true
},
dateCreated: {
type: String,
required: true
},
subject: {
type: String,
required: true
},
message: {
type: String,
required: true
},
previousMessage: {
type: String,
required: true
},
nextMessage: {
type: String,
required: true
},
read: {
type:Boolean,
required: true
},
messageID: {
type: String,
required: true
}
});
var secondConn = mongoose.createConnection(config.database);
// On Connection
secondConn.on('connected', function(){
console.log("Connected to database "+ config.database);
});
// On Error
secondConn.on('error', function(err){
console.log("Database Error " + err);
});
var Messages = module.exports = secondConn.model('Messages', messageSchema);
module.exports.getAllUserMessages = function(user, callback){
var query = {createdBy: user};
Messages.find(query, callback);
};
module.exports.getAllRecpMessages = function(user, callback){
var query = {recipients: user};
Messages.find(query, callback);
};
module.exports.deleteMessage = function(list, callback){
var query, i;
for(i = 0; i < list.length; i++)
{
query = { messageID: list[i].messageID};
Messages.remove(query, function(err){
});
}
};
module.exports.createMessage = function(message, callback){
message.save(function(err, doc){
if(err) throw err;
if(doc === null)
{
callback(null, false);
}
else
{
callback(null, true);
}
});
};
// Returns false if no other message has the same ID
module.exports.checkMessageID = function(message, callback){
var query = {messageID: message.messageID};
Messages.findOne(query, function(err, message){
if(err) throw err;
if(message === null)
{
callback(null, false);
}
else
{
callback(null, true);
}
});
};
&#39; / users / messages&#39;的角度打字稿:
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
import { FlashMessagesService } from 'angular2-flash-messages';
@Component({
selector: 'app-messages',
templateUrl: './messages.component.html',
styleUrls: ['./messages.component.css']
})
export class MessagesComponent implements OnInit {
createdBy: String;
recipients: String;
subject: String;
message: String;
previousMessage: String;
nextMessage: String;
user: Object;
constructor(private authService: AuthService,
private router: Router,
private flashMessage: FlashMessagesService
) { }
ngOnInit() {
this.authService.getProfile().subscribe(profile => {
this.user = profile.user;
this.createdBy = profile.user.username;
},
err => {
console.log(err);
return false;
});
}
// Need to create Message object and pass to Back End
newMessage(){
const newMessage = {
createdBy: this.createdBy,
recipients: this.recipients,
subject: this.subject,
message: this.message,
previousMessage: " ",
nextMessage: " "
}
this.authService.newMessage(this.user, newMessage).subscribe(data => {
if(data.success){
this.authService.storeUserData(data.token, data.user);
console.log(data);
this.router.navigate(['profile']);
}else{
console.log(data);
this.router.navigate(['dashboard']);
}
});
}
getMessages(){
this.authService.getMessages(this.user).subscribe(data => {
if(data.success){
this.authService.storeUserData(data.token, data.user);
this.router.navigate(['messages']);
console.log(data);
}else{
this.router.navigate(['dashboard']);
}
});
}
}
Angular auth服务:
import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';
import { tokenNotExpired } from 'angular2-jwt';
@Injectable()
export class AuthService {
authToken: any;
user: any;
message: any;
constructor(private http: Http) { }
// Need to pass Message object to Front End
newMessage(user, message){
console.log(user.username + " " + message.createdBy);
let headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type', 'application/json');
var info = {user, message};
return this.http.post('/users/newmessages', user, {headers: headers, body: info})
.map(res => res.json());
}
getMessages(user){
let headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type', 'application/json');
return this.http.post('/users/messages', user, {headers: headers})
.map(res => res.json());
}
registerUser(user){
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('/users/register', user, {headers: headers})
.map(res => res.json());
}
authenticateUser(user){
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('/users/authenticate', user, {headers: headers})
.map(res => res.json());
}
changePassword(user){
let headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type', 'application/json');
return this.http.post('/users/changepassword', user, {headers: headers})
.map(res => res.json());
}
getProfile(){
let headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type', 'application/json');
return this.http.get('/users/profile', {headers: headers})
.map(res => res.json());
}
storeUserData(token, user){
localStorage.setItem('id_token', token);
localStorage.setItem('user', JSON.stringify(user));
this.authToken = token;
this.user = user;
}
loadToken(){
const token = localStorage.getItem('id_token');
this.authToken = token;
}
loggedIn(){
return tokenNotExpired('id_token');
}
logout(){
this.authToken = null;
this.user = null;
localStorage.clear();
}
}
以防万一,这里是Mongoose Schema的部分用户模型:
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var config = require('../config/database');
// User Schema
var userSchema = mongoose.Schema({
name: {
type: String
},
email:{
type: String,
required: true
},
username: {
type: String,
required: true
},
password: {
type: String,
required: true
},
verify: {
type: Boolean,
required: true
}
});
答案 0 :(得分:3)
我遇到了同样的问题
只需console.log jwt_payload即可查看_id在哪里
在我的代码中,我有jwt_payload.data._id
删除.data对我的案子有帮助
答案 1 :(得分:2)
哇,修好了!
在&#39; / users / messages&#39;的Angular打字稿中:
// Need to create Message object and pass to Back End
newMessage(){
const newMessage = {
createdBy: this.createdBy,
recipients: this.recipients,
subject: this.subject,
message: this.message,
previousMessage: " ",
nextMessage: " "
}
this.authService.newMessage(this.user, newMessage).subscribe(data => {
if(data.success){
this.authService.storeUserData(data.token, data.user); < Erased that line
console.log(data);
this.router.navigate(['profile']);
}else{
console.log(data);
this.router.navigate(['dashboard']);
}
});
}
TL; DR解释,我正在传递未定义的数据&#39;这是从后端给出的。我删除了标记的行,以确保我在发送消息后不存储用户数据...因为我不需要。
感谢所有帮助我的人!