Node.js passport github有时无法读取id的属性

Node.js passport github有时无法读取id的属性,node.js,express,passport.js,Node.js,Express,Passport.js,passport github很难了解req.user。以下代码在几分钟前工作,现在我收到了这个错误 TypeError:无法读取未定义的属性“id” 在这条线上显示 var-token=jwt.sign({id:req.user.id},process.env.jwt\u SECRET) 我在passport本地策略方面没有这个问题,我确实配置了一个存储。这可能是序列化的问题吗 或者可能是因为我对路由路径进行了大量测试,以至于github api在一段时间后停止工作 routes/users.

passport github很难了解req.user。以下代码在几分钟前工作,现在我收到了这个错误

TypeError:无法读取未定义的属性“id”

在这条线上显示

var-token=jwt.sign({id:req.user.id},process.env.jwt\u SECRET)

我在passport本地策略方面没有这个问题,我确实配置了一个存储。这可能是序列化的问题吗

或者可能是因为我对路由路径进行了大量测试,以至于github api在一段时间后停止工作

routes/users.js

router.get('/auth/github', passport.authenticate('github', {
  session:true,
  scope:[ 'id', 'profile']
}));
router.get('/auth/github/callback', (req, res, next) => {
  passport.authenticate('github', (user) => {

    // Successful authentication, redirect home.
    var token = jwt.sign({ id: req.user.id},  process.env.JWT_SECRET );
    // res.cookie("jwt", token, { expires: new Date(Date.now() + 10*1000*60*60*24)});
    jwt.verify(token, process.env.JWT_SECRET, function(err, data){
      console.log(err, data);
    })
    res.status(200).send({message:"github user signed in", auth: true});
    // console.log(`frontid ${req.user.id}`)
    // res.redirect('')
    console.log('this works', token);
  })(req, res, next);

});
const passport = require("passport");
const GitHubStrategy = require('passport-github2').Strategy;
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
const models = require("../models/");

// passport.serializeUser((user, done) => {
//   // push to session
//   done(null, user.id);
//   console.log(user.id)
// });


// passport.deserializeUser((id, done) => {
//   models.User.findOne({
//     where: {
//       id,
//     },
//   }).then(user => done(null, user))
//   .catch(done);
// });

passport.use(
  new GitHubStrategy(
    {
      clientID: process.env.clientID,
      clientSecret: process.env.secret,
      callbackURL: 'http://127.0.0.1:8000/api/users/auth/github/callback',
      passReqToCallback: true,
      profileFields: ['id', 'login']
    },
     (req, accessToken, refreshToken, profile, done) => {
       const { id,  login, email} = profile._json;  
       console.log(`backbro ${id}`);
      //  console.log(req)
       models.User.find({
         where:{
           id: id
         }
       }).then( user => {
        //  if user is found
         if(user){
           return done(null, user)
         }
        //  else create new user
         else{
           models.User.create({
             id: id,
             username:login,
             email: email,
             createdAt: Date.now()
           }).then( user => {
             console.log('github user created');
             return done(null, user);
           })
         }
       })
    }
  )
);

passport.serializeUser((user, done) => {
  // push to session
  done(null, user.id);
});

passport.deserializeUser((userId, done) => {

  // console.log('calling deserial' + userId); 
  // // TODO: findByPk syntax? findById deprecated? Try later after sucessfully record data in DB
  models.User
      .find({ where: { id: userId } })
      .then(function(user){
        // console.log(user);
       return  done(null, userId);
      }).catch(function(err){
        done(err, null);
      });
  // return done(null, id);
});


module.exports = passport;
var sequelize = new Sequelize(
  process.env.POSTGRES_DB, 
  process.env.POSTGRES_USER, 
  process.env.POSTGRES_PASSWORD,{
    "dialect": "sqlite",
    "storage": "./session.sqlite"
});

myStore = new SequelizeStore({
  db:sequelize,
})

if (!process.env.PORT) {
  require('dotenv').config()
}
// console.log(process.env.DATABASE_URL);
if (!process.env.PORT) {
  console.log('[api][port] 8000 set as default')
  console.log('[api][header] Access-Control-Allow-Origin: * set as default')
} else {
  console.log('[api][node] Loaded ENV vars from .env file')
  console.log(`[api][port] ${process.env.PORT}`)
  console.log(`[api][header] Access-Control-Allow-Origin: ${process.env.ALLOW_ORIGIN}`)
}
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'build')));
app.use(cookieParser());


// We need a store in order to save sessions, instead of the sessions clearing out on us :)
app.use(session({
  store: myStore,
  saveUninitialized: false,
  resave:false,
  cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 },  // 30 days
  secret : process.env.JWT_SECRET,

}));

myStore.sync();
require('./config/passport')(passport); // PASSPORT Init
require('./config/passport-github'); // PASSPORT Init
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({ extended:false})); 
app.use(bodyParser.json());
app.use(function(req, res, next) {
  res.locals.user = req.user; // This is the important line
  // req.session.user = user
  console.log(res.locals.user);
  next();
});
// this code may be useless or useful, still trying to understand cors. 
app.use((req, res, next) => {
  const { headers } = req;
  res.header('Access-Control-Allow-Origin', headers.origin);
  res.header('Access-Control-Allow-Headers', headers);
  res.header('Access-Control-Allow-Credentials', true);
  next();
});
app.use(cors({
  origin: process.env.ALLOW_ORIGIN,
  credentials: true,
  allowedHeaders: 'X-Requested-With, Content-Type, Authorization',
  methods: 'GET, POST, PATCH, PUT, POST, DELETE, OPTIONS'
}))
app.use('/api/users', userRoute );
app.use('/api/posts', postRoute );

// In order to use REACT + EXPRESS we need the following code, alone with a build
// in the client folder we run a npm run build in the client folder then it is referred
// in the following code. 
app.use(express.static(path.join(__dirname, 'client/build')));
if(process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, 'client/build')));
  //
  app.get('*', (req, res) => {
    res.sendfile(path.join(__dirname = 'client/build/index.html'));
  })
}
//build mode
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname+'/client/public/index.html'));
})
models.sequelize.sync().then(function() {
  app.listen(PORT, host, () => {
    console.log('[api][listen] http://localhost:' + PORT)
  })
})
passport github.js

router.get('/auth/github', passport.authenticate('github', {
  session:true,
  scope:[ 'id', 'profile']
}));
router.get('/auth/github/callback', (req, res, next) => {
  passport.authenticate('github', (user) => {

    // Successful authentication, redirect home.
    var token = jwt.sign({ id: req.user.id},  process.env.JWT_SECRET );
    // res.cookie("jwt", token, { expires: new Date(Date.now() + 10*1000*60*60*24)});
    jwt.verify(token, process.env.JWT_SECRET, function(err, data){
      console.log(err, data);
    })
    res.status(200).send({message:"github user signed in", auth: true});
    // console.log(`frontid ${req.user.id}`)
    // res.redirect('')
    console.log('this works', token);
  })(req, res, next);

});
const passport = require("passport");
const GitHubStrategy = require('passport-github2').Strategy;
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
const models = require("../models/");

// passport.serializeUser((user, done) => {
//   // push to session
//   done(null, user.id);
//   console.log(user.id)
// });


// passport.deserializeUser((id, done) => {
//   models.User.findOne({
//     where: {
//       id,
//     },
//   }).then(user => done(null, user))
//   .catch(done);
// });

passport.use(
  new GitHubStrategy(
    {
      clientID: process.env.clientID,
      clientSecret: process.env.secret,
      callbackURL: 'http://127.0.0.1:8000/api/users/auth/github/callback',
      passReqToCallback: true,
      profileFields: ['id', 'login']
    },
     (req, accessToken, refreshToken, profile, done) => {
       const { id,  login, email} = profile._json;  
       console.log(`backbro ${id}`);
      //  console.log(req)
       models.User.find({
         where:{
           id: id
         }
       }).then( user => {
        //  if user is found
         if(user){
           return done(null, user)
         }
        //  else create new user
         else{
           models.User.create({
             id: id,
             username:login,
             email: email,
             createdAt: Date.now()
           }).then( user => {
             console.log('github user created');
             return done(null, user);
           })
         }
       })
    }
  )
);

passport.serializeUser((user, done) => {
  // push to session
  done(null, user.id);
});

passport.deserializeUser((userId, done) => {

  // console.log('calling deserial' + userId); 
  // // TODO: findByPk syntax? findById deprecated? Try later after sucessfully record data in DB
  models.User
      .find({ where: { id: userId } })
      .then(function(user){
        // console.log(user);
       return  done(null, userId);
      }).catch(function(err){
        done(err, null);
      });
  // return done(null, id);
});


module.exports = passport;
var sequelize = new Sequelize(
  process.env.POSTGRES_DB, 
  process.env.POSTGRES_USER, 
  process.env.POSTGRES_PASSWORD,{
    "dialect": "sqlite",
    "storage": "./session.sqlite"
});

myStore = new SequelizeStore({
  db:sequelize,
})

if (!process.env.PORT) {
  require('dotenv').config()
}
// console.log(process.env.DATABASE_URL);
if (!process.env.PORT) {
  console.log('[api][port] 8000 set as default')
  console.log('[api][header] Access-Control-Allow-Origin: * set as default')
} else {
  console.log('[api][node] Loaded ENV vars from .env file')
  console.log(`[api][port] ${process.env.PORT}`)
  console.log(`[api][header] Access-Control-Allow-Origin: ${process.env.ALLOW_ORIGIN}`)
}
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'build')));
app.use(cookieParser());


// We need a store in order to save sessions, instead of the sessions clearing out on us :)
app.use(session({
  store: myStore,
  saveUninitialized: false,
  resave:false,
  cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 },  // 30 days
  secret : process.env.JWT_SECRET,

}));

myStore.sync();
require('./config/passport')(passport); // PASSPORT Init
require('./config/passport-github'); // PASSPORT Init
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({ extended:false})); 
app.use(bodyParser.json());
app.use(function(req, res, next) {
  res.locals.user = req.user; // This is the important line
  // req.session.user = user
  console.log(res.locals.user);
  next();
});
// this code may be useless or useful, still trying to understand cors. 
app.use((req, res, next) => {
  const { headers } = req;
  res.header('Access-Control-Allow-Origin', headers.origin);
  res.header('Access-Control-Allow-Headers', headers);
  res.header('Access-Control-Allow-Credentials', true);
  next();
});
app.use(cors({
  origin: process.env.ALLOW_ORIGIN,
  credentials: true,
  allowedHeaders: 'X-Requested-With, Content-Type, Authorization',
  methods: 'GET, POST, PATCH, PUT, POST, DELETE, OPTIONS'
}))
app.use('/api/users', userRoute );
app.use('/api/posts', postRoute );

// In order to use REACT + EXPRESS we need the following code, alone with a build
// in the client folder we run a npm run build in the client folder then it is referred
// in the following code. 
app.use(express.static(path.join(__dirname, 'client/build')));
if(process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, 'client/build')));
  //
  app.get('*', (req, res) => {
    res.sendfile(path.join(__dirname = 'client/build/index.html'));
  })
}
//build mode
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname+'/client/public/index.html'));
})
models.sequelize.sync().then(function() {
  app.listen(PORT, host, () => {
    console.log('[api][listen] http://localhost:' + PORT)
  })
})
路由/当前用户

router.get("/current_user", (req, res) => {
  if(req.user){
    res.status(200).send({ user: req.user});
  } else {
    res.json({ user:null})
  }
});
app.js

router.get('/auth/github', passport.authenticate('github', {
  session:true,
  scope:[ 'id', 'profile']
}));
router.get('/auth/github/callback', (req, res, next) => {
  passport.authenticate('github', (user) => {

    // Successful authentication, redirect home.
    var token = jwt.sign({ id: req.user.id},  process.env.JWT_SECRET );
    // res.cookie("jwt", token, { expires: new Date(Date.now() + 10*1000*60*60*24)});
    jwt.verify(token, process.env.JWT_SECRET, function(err, data){
      console.log(err, data);
    })
    res.status(200).send({message:"github user signed in", auth: true});
    // console.log(`frontid ${req.user.id}`)
    // res.redirect('')
    console.log('this works', token);
  })(req, res, next);

});
const passport = require("passport");
const GitHubStrategy = require('passport-github2').Strategy;
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
const models = require("../models/");

// passport.serializeUser((user, done) => {
//   // push to session
//   done(null, user.id);
//   console.log(user.id)
// });


// passport.deserializeUser((id, done) => {
//   models.User.findOne({
//     where: {
//       id,
//     },
//   }).then(user => done(null, user))
//   .catch(done);
// });

passport.use(
  new GitHubStrategy(
    {
      clientID: process.env.clientID,
      clientSecret: process.env.secret,
      callbackURL: 'http://127.0.0.1:8000/api/users/auth/github/callback',
      passReqToCallback: true,
      profileFields: ['id', 'login']
    },
     (req, accessToken, refreshToken, profile, done) => {
       const { id,  login, email} = profile._json;  
       console.log(`backbro ${id}`);
      //  console.log(req)
       models.User.find({
         where:{
           id: id
         }
       }).then( user => {
        //  if user is found
         if(user){
           return done(null, user)
         }
        //  else create new user
         else{
           models.User.create({
             id: id,
             username:login,
             email: email,
             createdAt: Date.now()
           }).then( user => {
             console.log('github user created');
             return done(null, user);
           })
         }
       })
    }
  )
);

passport.serializeUser((user, done) => {
  // push to session
  done(null, user.id);
});

passport.deserializeUser((userId, done) => {

  // console.log('calling deserial' + userId); 
  // // TODO: findByPk syntax? findById deprecated? Try later after sucessfully record data in DB
  models.User
      .find({ where: { id: userId } })
      .then(function(user){
        // console.log(user);
       return  done(null, userId);
      }).catch(function(err){
        done(err, null);
      });
  // return done(null, id);
});


module.exports = passport;
var sequelize = new Sequelize(
  process.env.POSTGRES_DB, 
  process.env.POSTGRES_USER, 
  process.env.POSTGRES_PASSWORD,{
    "dialect": "sqlite",
    "storage": "./session.sqlite"
});

myStore = new SequelizeStore({
  db:sequelize,
})

if (!process.env.PORT) {
  require('dotenv').config()
}
// console.log(process.env.DATABASE_URL);
if (!process.env.PORT) {
  console.log('[api][port] 8000 set as default')
  console.log('[api][header] Access-Control-Allow-Origin: * set as default')
} else {
  console.log('[api][node] Loaded ENV vars from .env file')
  console.log(`[api][port] ${process.env.PORT}`)
  console.log(`[api][header] Access-Control-Allow-Origin: ${process.env.ALLOW_ORIGIN}`)
}
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'build')));
app.use(cookieParser());


// We need a store in order to save sessions, instead of the sessions clearing out on us :)
app.use(session({
  store: myStore,
  saveUninitialized: false,
  resave:false,
  cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 },  // 30 days
  secret : process.env.JWT_SECRET,

}));

myStore.sync();
require('./config/passport')(passport); // PASSPORT Init
require('./config/passport-github'); // PASSPORT Init
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({ extended:false})); 
app.use(bodyParser.json());
app.use(function(req, res, next) {
  res.locals.user = req.user; // This is the important line
  // req.session.user = user
  console.log(res.locals.user);
  next();
});
// this code may be useless or useful, still trying to understand cors. 
app.use((req, res, next) => {
  const { headers } = req;
  res.header('Access-Control-Allow-Origin', headers.origin);
  res.header('Access-Control-Allow-Headers', headers);
  res.header('Access-Control-Allow-Credentials', true);
  next();
});
app.use(cors({
  origin: process.env.ALLOW_ORIGIN,
  credentials: true,
  allowedHeaders: 'X-Requested-With, Content-Type, Authorization',
  methods: 'GET, POST, PATCH, PUT, POST, DELETE, OPTIONS'
}))
app.use('/api/users', userRoute );
app.use('/api/posts', postRoute );

// In order to use REACT + EXPRESS we need the following code, alone with a build
// in the client folder we run a npm run build in the client folder then it is referred
// in the following code. 
app.use(express.static(path.join(__dirname, 'client/build')));
if(process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, 'client/build')));
  //
  app.get('*', (req, res) => {
    res.sendfile(path.join(__dirname = 'client/build/index.html'));
  })
}
//build mode
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname+'/client/public/index.html'));
})
models.sequelize.sync().then(function() {
  app.listen(PORT, host, () => {
    console.log('[api][listen] http://localhost:' + PORT)
  })
})

正式文档您的客户从不调用
/auth/github/callback
路由。在
serializeUser
done(null,token);
)处创建用户令牌,并在
deserializeUser
(passport.deserializeUser((token,done))处验证令牌,最后在私有路由中获取用户,如
/profile
@hoangdv ok将尝试此操作,并让您知道它是如何运行的。@hoangdv似乎对我没有任何帮助,在检查当前用户时仍然显示null。使用sequelizeWhere检查当前用户时,获得了github passport运行的一个很好的示例?@hoangdv刚刚进行了编辑,还包括了app.js。如果您觉得有什么不对劲,请告诉我。您的客户从未调用过官方文档
/auth/github/callback
路由。在
serializeUser
处创建用户令牌(
done(null,token);
)并在
deserializeUser
处验证令牌(passport.deserializeUser((代币,完成),最后在私有路由中获取用户,如
/profile
@hoangdv ok将尝试此操作,并让您知道它是如何运行的。@hoangdv似乎对我没有任何帮助,在检查当前用户时仍然显示null。使用sequelizeWhere检查当前用户时,获得了github passport运行的一个很好的示例?@hoangdv刚刚做了一个编辑,还包括app.js。如果你觉得有什么不对劲,请告诉我。