无法读取未定义的属性(读取'ES6'),

问题描述 投票:0回答:1

app.js代码-

我不知道为什么这会在节点模块中出错 -

npm mongoose-findorcreate

我检查了节点模块,但ES6没有错,我也附上下面的模块代码

// jshint esversion:6
require('dotenv').config()
const express=require("express")
const bodyParser = require("body-parser")
const ejs=require("ejs")
const mongoose=require("mongoose")
const bcrypt=require("bcrypt")
const session=require("express-session")
const passport=require("passport")
const flash = require('connect-flash')
const passportLocalMongoose = require("passport-local-mongoose");
const findOrCreate = require("mongoose-findorcreate");
const LocalStrategy=require("passport-local").Strategy;
const GoogleStrategy = require('passport-google-oauth20').Strategy;

const app=express();
app.use(express.urlencoded({extended:false}))  //Not using bodyParser, using Express in-built body parser instead
app.set("view engine","ejs")
app.use(express.static("public"))
app.use(bodyParser.urlencoded({extended: true}));

app.use(session({
    secret:"Justarandomstring.",
    resave:false,
    saveUninitialized:false
}))

app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

mongoose.connect("mongodb://127.0.0.1:27017/userDB")
const userSchema= new mongoose.Schema({
    username : String,
    password : String,
    googleId: String
});
userSchema.plugin(passportLocalMongoose);
userSchema.plugin(findOrCreate);

const User=new mongoose.model("User",userSchema)

//Creating Local Strategy. passport-local-mongoose 3 lines of code for Strategy, 
//Serialiazation, Deserialization not working due to recent changes in Mongoose 7
passport.use(new LocalStrategy((username,password,done)=>{  //done is a callback function
    try{
        User.findOne({username:username}).then(user=>{
            if (!user){
                return done(null,false, {message:"Incorrect Username"})
            }
            //using bcrypt to encrypt passoword in register post route and compare function in login post round. 
            //login post route will check here during authentication so need to use compare here  
            bcrypt.compare(password,user.password,function(err,result){ 
                if (err){
                    return done(err)
                }
                
                if (result) {
                    return done(null,user)
                }
                else {
                    return done (null,false, {message:"Incorrect Password"})
                }
            })
            
        })
    }
    catch (err){
        return done(err)
    }
    
}))
//serialize user
passport.serializeUser(function(user, done) {
    done(null, user.id);
});

//deserialize user  
passport.deserializeUser(function(id, done) {
    console.log("Deserializing User")
    try {
        User.findById(id).then(user=>{
            done(null,user);
        })
    }
    catch (err){
        done(err);
    }
});

passport.use(new GoogleStrategy({
    clientID: process.env.CLIENT_ID,
    clientSecret:process.env.CLIENT_SECRET,
    callbackURL: "http://localhost:3000/auth/google/secrets", 
    userProfileURL: "https://www.googleapis.com//oauth2/v3/userinfo"
  },
  (accessToken, refreshToken, profile, cb)=>{
    console.log(profile);
    User.findOrCreate({ googleId: profile.id }, (err, user) =>{
      return cb(err, user);
    });
    
  }
));

//get routes
app.get("/",function(req,res){
    res.render("home")
})

app.get('/auth/google',
  passport.authenticate('google', { scope: ['profile'] }));

app.get('/auth/google/secrets', 
  passport.authenticate("google", { failureRedirect: '/login'}),
  function(req, res) {
    // Successful authentication, redirect home.
    res.redirect("/secrets");
  });

app.get("/login",function(req,res){
    console.log(req.flash("error"))
    res.render("login");
})

app.get("/register",function(req,res){
    res.render("register")
})

app.get("/secrets",function(req,res){
    if (req.isAuthenticated()){
        res.render("secrets")
    }
    else {
        res.redirect("/login")
    }
})

app.get("/logout",function(req,res){
    req.logout(function(err){
        if(err){
            console.log(err)
        }
        res.redirect("/");
    });
    
})

//post routes
app.post("/register",function(req,res){
    bcrypt.hash(req.body.password,10,function(err,hash){  //10 is SaltRounds
        if (err){
            console.log(err)
        }
        const user= new User ({
            username:req.body.username,
            password:hash
        })
        user.save()
        
        passport.authenticate('local')(req,res,()=>{res.redirect("/secrets")}) 
    })
})   

app.post('/login',passport.authenticate('local',
    { successRedirect:"/secrets", failureRedirect: '/login', failureFlash:true}
));

//listen
app.listen(3000, ()=> {
    console.log("Server Running on Port 3000")
})

模块代码链接:

/*!
 * Mongoose findOrCreate Plugin
 * Copyright(c) 2012 Nicholas Penree <[email protected]>
 * MIT Licensed
 */
function findOrCreatePlugin(schema, options) {
  schema.statics.findOrCreate = function findOrCreate(conditions, doc, options, callback) {
    var self = this;
    // When using Mongoose 5.0.x and upper, we must use self.base.Promise
    var Promise = self.base.Promise.ES6 ? self.base.Promise.ES6 : self.base.Promise;
    if (arguments.length < 4) {
      if (typeof options === 'function') {
        // Scenario: findOrCreate(conditions, doc, callback)
        callback = options;
        options = {};
      } else if (typeof doc === 'function') {
        // Scenario: findOrCreate(conditions, callback);
        callback = doc;
        doc = {};
        options = {};
      } else {
        // Scenario: findOrCreate(conditions[, doc[, options]])
        return new Promise(function(resolve, reject) {
          self.findOrCreate(conditions, doc, options, function (ex, result, created) {
            if (ex) {
              reject(ex);
            } else {
              resolve({
                doc: result,
                created: created,
              });
            }
          });
        });
      }
    }
    this.findOne(conditions, function(err, result) {
      if (err || result) {
        if (options && options.upsert && !err) {
          self.update(conditions, doc, function(err, count) {
            self.findById(result._id, function(err, result) {
              callback(err, result, false);
            });
          });
        } else {
          callback(err, result, false);
        }
      } else {
        for (var key in doc) {
         conditions[key] = doc[key];
        }

        // If the value contain `$` remove the key value pair
        var keys = Object.keys(conditions);

        for (var z = 0; z < keys.length; z++) {
          var value = JSON.stringify(conditions[keys[z]]);
          if (value && value.indexOf('$') !== -1) {
            delete conditions[keys[z]];
          }
        }

        var obj = new self(conditions);
        obj.save(function(err) {
          callback(err, obj, true);
        });
      }
    });
  };
}

/**
 * Expose `findOrCreatePlugin`.
 */

module.exports = findOrCreatePlugin;

我收到以下错误:

TypeError: Cannot read properties of undefined (reading 'ES6')
    at Function.findOrCreate (C:\Users\KIIT\Desktop\Web Development\Secrets - Starting Code\node_modules\mongoose-findorcreate\index.js:10:37)
    at Strategy._verify (C:\Users\KIIT\Desktop\Web Development\Secrets - Starting Code\app.js:101:10)
    at C:\Users\KIIT\Desktop\Web Development\Secrets - Starting Code\node_modules\passport-oauth2\lib\strategy.js:205:24
    at C:\Users\KIIT\Desktop\Web Development\Secrets - Starting Code\node_modules\passport-google-oauth20\lib\strategy.js:122:5
    at passBackControl (C:\Users\KIIT\Desktop\Web Development\Secrets - Starting Code\node_modules\oauth\lib\oauth2.js:134:9)
    at IncomingMessage.<anonymous> (C:\Users\KIIT\Desktop\Web Development\Secrets - Starting Code\node_modules\oauth\lib\oauth2.js:157:7)
    at IncomingMessage.emit (node:events:525:35)
    at endReadableNT (node:internal/streams/readable:1359:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
node.js oauth passport.js ejs
1个回答
0
投票

本文来自Angela Yu 的Complete Web development Bootcamp。对此的一个非常小的修复:在 GoogleStrategy 中,只需将 findOrCreate 方法替换为 findOne。

passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: 'http://localhost:3000/auth/google/secrets'
  },
  async function (accessToken, refreshToken, profile, done) {
    try {
      console.log(profile);
      // Find or create user in your database
      let user = await User.findOne({ googleId: profile.id });
      if (!user) {
        // Create new user in database
        const username = Array.isArray(profile.emails) && profile.emails.length > 0 ? profile.emails[0].value.split('@')[0] : '';
        const newUser = new User({
          username: profile.displayName,
          googleId: profile.id
        });
        user = await newUser.save();
      }
      return done(null, user);
    } catch (err) {
      return done(err);
    }
  }
));

这是我实现 Google 登录和 Facebook 登录的 app.js 的完整代码:

   require("dotenv").config();
const express=require("express");
const app=express();
const ejs=require("ejs");
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const mongoose=require("mongoose");
const bcrypt = require("bcrypt");
const session=require("express-session");
const passport=require("passport");
const FacebookStrategy = require('passport-facebook').Strategy;
const LocalStrategy=require("passport-local").Strategy;

app.use(express.urlencoded({extended:false})) ; //Not using bodyParser, using Express in-built body parser instead
app.set("view engine","ejs");
app.use(express.static("public"));

app.use(session({
    secret:"Our little secret.",
    resave:false,
    saveUninitialized:false
}));

app.use(passport.initialize());
app.use(passport.session());

mongoose.connect("mongodb://127.0.0.1:27017/userDB");
const userSchema= new mongoose.Schema({
    username : String,
    password : String,
    googleId : String,
    facebookId : String,
    secret : String
});

const User=new mongoose.model("User",userSchema);

//Creating Local Strategy. passport-local-mongoose 3 lines of code for Strategy,
//Serialiazation, Deserialization not working due to recent changes in Mongoose 7
passport.use(new LocalStrategy((username,password,done)=>{  //done is a callback function

        User.findOne({username:username})
        .then(user=>{

            if (!user){
                return done(null,false, {message:"Incorrect Username"})
            }
 //using bcrypt to encrypt passoword in register post route and compare function in login post round.
 //login post route will check here during authentication so need to use compare here
            bcrypt.compare(password, user.password)
            .then((isMatch)=>{
              if (isMatch) {
                  return done(null,user)
              }
              else {
                  return done (null,false, {message:"Incorrect Password"})
              }
            })
            .catch((err)=>{return done(err)});
        })
        .catch((err)=>{ return done(err);});

}));

//serialize user
passport.serializeUser(function(user, done) {
    done(null, user.id);
  });

//deserialize user
passport.deserializeUser(function(id, done) {

        User.findById(id).then(user=>{
            done(null, user);
        })
        .catch((err)=>{ return done(err); });

  });

  passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: 'http://localhost:3000/auth/google/secrets'
  },
  async function (accessToken, refreshToken, profile, done) {
    try {
      console.log(profile);
      // Find or create user in your database
      let user = await User.findOne({ googleId: profile.id });
      if (!user) {
        // Create new user in database
        const username = Array.isArray(profile.emails) && profile.emails.length > 0 ? profile.emails[0].value.split('@')[0] : '';
        const newUser = new User({
          username: profile.displayName,
          googleId: profile.id
        });
        user = await newUser.save();
      }
      return done(null, user);
    } catch (err) {
      return done(err);
    }
  }
));

passport.use(new FacebookStrategy({
    clientID: process.env.FACEBOOK_APP_ID,
    clientSecret: process.env.FACEBOOK_APP_SECRET,
    callbackURL: 'http://localhost:3000/auth/facebook/secrets'
  },
  async function (accessToken, refreshToken, profile, done) {
    try {
      console.log(profile);
      // Find or create user in your database
      let user = await User.findOne({ facebookId: profile.id });
      if (!user) {
        // Create new user in database
        const newUser = new User({
          username: profile.displayName,
          facebookId: profile.id
        });
        user = await newUser.save();
      }
      return done(null, user);
    } catch (err) {
      return done(err);
    }
  }
));

//get routes
app.get("/",function(req,res){
    res.render("home");
});

app.get("/login",function(req,res){
    res.render("login");
});

app.get("/register",function(req,res){
    res.render("register");
});

app.get("/secrets",function(req,res){

  User.find({secret: {$ne: null}})
  .then((foundUsers)=>{
    res.render("secrets", {usersWithSecrets: foundUsers})
  })
  .catch((err)=>{ console.log(err); });

});

app.get("/logout",function(req,res){
    req.logout(function(err){
        if(err){
            console.log(err);
        }
        res.redirect("/");
    });

});

app.get("/auth/google",
  passport.authenticate("google", { scope: ["profile"] }));

app.get("/auth/google/secrets",
  passport.authenticate("google", { failureRedirect: "/login" }),
  function(req, res) {
    // Successful authentication, redirect home.
    res.redirect("/secrets");
  });

  app.get('/auth/facebook',
  passport.authenticate('facebook'));

app.get('/auth/facebook/secrets',
  passport.authenticate('facebook', { failureRedirect: '/login' }),
  function (req, res) {
    // Successful authentication, redirect to secrets page.
    res.redirect('/secrets');
  });

app.route("/submit")
.get(function(req, res){
  if(req.isAuthenticated()){
    res.render("submit");
  }else {
    res.rediret("/login");
  }
})
.post(function(req, res){

  const submittedsecret = req.body.secret;

  User.findById(req.user.id)
  .then((foundUser)=> {
      if(foundUser){
        foundUser.secret = submittedsecret;
        foundUser.save()
        .then(()=>{ res.redirect("/secrets"); })
        .catch((err)=> { console.log(err);});
      }

   })
  .catch((err)=>{ console.log(err); });


});

//post routes

app.post("/register",function(req,res){
    bcrypt.hash(req.body.password,10,function(err,hash){  //10 is SaltRounds
        if (err){
            console.log(err);
        }
        const user= new User ({
            username:req.body.username,
            password:hash
        })
        user.save();

        passport.authenticate('local')(req,res,()=>{res.redirect("/secrets");})
    })
});



app.post('/login', passport.authenticate('local', { successRedirect:"/secrets", failureRedirect: '/login' }));

//listen
app.listen(3000, ()=> {
    console.log("Server Running on Port 3000");
});
© www.soinside.com 2019 - 2024. All rights reserved.