2017-06-04 1 views
0

Ich versuche, eine Nachricht in einer Datenbank zu schreiben, wenn der Benutzer eine Nachricht sendet. Ich benutze den MEAN Stack mit angular-cli.TypeError: Kann die Eigenschaft '_id' von undefined in MEAN nicht lesen Stack

Der Fehler Ich erhalte ist:

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) 

Hier ist jedes Stück Code, den ich verwende, um zu sehen, ob jemand kann herausfinden, was ich falsch mache.

Knoten mit Express befindet sich in '/ Benutzer:

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 Schema und Code:

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); 
    } 
    }); 
}; 
hier ist mein Teil-Benutzermodell aus dem Mongoose Schema

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(); 
    } 
} 

Nur für den Fall,:

Angular Typoskript für '/ users/messages':

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 Service

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

Es sieht so aus, als ob der Fehler in Ihrem PassportJS-Setup-Code in der folgenden Zeile angezeigt wird: 'User.getUserByID (jwt_payload._doc._id, function (err, user) {...'. Können Sie 'console.log (jwt_payload) 'da und stellen Sie sicher, dass es einen _doc-Schlüssel enthält und dass es einen _id-Schlüssel enthält? –

+0

Ich vergaß zu erwähnen, dass dies mit Postboten funktioniert, wenn ich es die Pass-Authentifizierungsüberprüfung nehme, aber es hat nie von vorne nach hinten funktioniert. –

+0

Woher kommt das '_doc'? –

Antwort

0

Puh, repariert es !

im Winkel Typoskript für '/ users/messages':

// 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 Erklärung, ich wurde eine nicht definierte 'Daten' vorbei, die vom Back-End gegeben wurde. Ich habe die markierte Zeile gelöscht, um sicherzustellen, dass ich keine Benutzerdaten nach dem Senden einer Nachricht speichern möchte ... Weil ich es nicht tun muss.

Danke an alle, die mir geholfen haben!

Verwandte Themen