首页 > 解决方案 > TypeError Passport JS 用户名属性未定义

问题描述

我是 Reactjs 和 nodejs 的初学者,试图制作我的第一个全栈应用程序。在我的 postjob 模式中,我想要发布者字段中当前登录用户的用户名。Passport 有一个req.user命令可以获取当前用户的详细信息,但是每当我尝试使用它时,它都会出现类型错误。如果你们需要任何其他文件,请告诉我

作业后模式

const mongoose=require('mongoose')

const postjobtemplate= new mongoose.Schema({

    jobtitle:{
        type:String,
        required:true
    },
    company:{
        type:String,
        required:true
    },
    officelocation:{
        type:String,
        required:true
    },
    jobtype:{
        type:String,
        required:true
    },
    publisher:{           ///<=HERE
        type:String,
        required:true
    },
    date:{
        type:Date,
        default:Date.now
    }
})

module.exports=mongoose.model("postjobtable",postjobtemplate)

路由js

router.post('/postjob',async(request,response,next)=>{
    const postjob=new postjobtemplatecopy({
        jobtitle:request.body.jobtitle,
        company:request.body.company,
        officelocation:request.body.officelocation,
        jobtype:request.body.jobtype,
        publisher:request.user.username, //////<=HERE

    })
    postjob.save()
    .then(data=>{
        response.json(data)

    })
    .catch(error=>{
        response.json(error)
    })
});

router.post("/login", (req, res, next) => {
    passport.authenticate("local", (err, user, info) => {
      if (err) throw err;
      if (!user) res.send("No User Exists");
      else {
        req.logIn(user, (err) => {
          if (err) throw err;
          res.status(200).send("Successfully Authenticated");
    
        });
      }
    })(req, res, next);
  });

服务器js

const express =require('express')
const app=express()
const mongoose=require('mongoose')
const dotenv=require('dotenv')
const routes=require('./routes/routes')
const cors=require('cors')
const passport=require("passport")
const passportlocal = require("passport-local").Strategy;
const bodyParser=require("body-parser")
const session=require("express-session") 
const cookieparser=require('cookie-parser')

dotenv.config();
mongoose.connect(process.env.DB_CONNECT,{useNewUrlParser:true},()=>
console.log("database connected")
);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(express.urlencoded({ extended: true }));

app.use(cors({
    origin:'http://localhost:3000',
    credentials:true
}))

app.use(session({
    secret:'secret',
    resave:true,
    saveUninitialized:true
}))

app.use(cookieparser("secret"))
app.use(passport.initialize());
app.use(passport.session());
require('./passport-config')(passport);
app.use(express.json())
app.use('/api',routes)

app.listen(4002,()=>console.log("server running on port 4002"))

module.exports = app;

护照配置

const User = require("./models/user");
const bcrypt = require("bcryptjs");
const localStrategy = require("passport-local").Strategy;

module.exports = function (passport) {
  passport.use(
    new localStrategy((username, password, done) => {
      User.findOne({ username: username }, (err, user) => {
        if (err) throw err;
        if (!user) return done(null, false);
        bcrypt.compare(password, user.password, (err, result) => {
          if (err) throw err;
          if (result === true) {
            return done(null, user);
          } else {
            return done(null, false);
          }
        });
      });
    })
  );

  passport.serializeUser((user, cb) => {
    cb(null, user.id);
  });
  passport.deserializeUser((id, cb) => {
    User.findOne({ _id: id }, (err, user) => {
      const userInformation = {
        username: user.username,
      };
      cb(err, userInformation);
    });
  });
};

标签: node.jsexpressmongoosepassport.js

解决方案


您收到 typeError 是因为未正确发送/接收用户名。在您的发布路线中更改此行:publisher: request.user.username,为此:(publisher: request.body.username,我假设您是从前端作为用户名发送的,如果不是,则将来自 React 的请求包含在您的代码中会很有用)这样您实际上会收到您从前端发送的数据。此外,如果您使用的是用户名以外的其他字段,则需要在您的护照策略中指定它,如下所示:

passport.use(
    "yourStrategyName", //here you are naming the strategy to be used in your route
    new localStrategy( {
    usernameField: "publisher", //here you are telling passport to use "publisher" as a username
  },(publisher, password, done) => {
      User.findOne({ publisher }, (err, user) => { //changed to the field name in database
        if (err) throw err;
        if (!user) return done(null, false);
        bcrypt.compare(password, user.password, (err, result) => {
          if (err) throw err;
          if (result === true) {
            return done(null, user);
          } else {
            return done(null, false);
          }
        });
      });
    })
  );

在你的 route.js 中:

  router.post("/login", (req, res, next) => {
    passport.authenticate("yourStrategyName", (err, user, info) => { //include the strategy name as the first parameter
      if (err) throw err;
      if (!user) res.send("No User Exists");
      else {
        req.logIn(user, (err) => {
          if (err) throw err;
          res.status(200).send("Successfully Authenticated");
    
        });
      }
    })(req, res, next);
  });

推荐阅读