首页 > 解决方案 > 认证后护照不保存req.user

问题描述

目前用户可以使用 github 登录,我可以看到它在回调函数和护照 github 文件中获取了 req.user

  console.log(`frontid ${req.user.id}`) // logs user id

和护照

   console.log(`backbro ${id}`); // logs an id

然而,当我走这条路时,github用户返回null,我不知道为什么。有几次,我看到登录的 github 用户在 current_user 路由中返回,但是我现在很少看到它。它有时显示,有时不显示。有点奇怪。会不会是会话问题?

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

是的,我查看了以下链接,仍然没有合适的答案。

Node + Express + Passport:req.user 未定义

使用快速服务器、passport.js 进行 Twitter 身份验证后 req.user 未定义

我访问此链接的方式是明确调用

本地主机:8000/api/users/auth/github

在地址栏中。

路线/用户

router.get('/auth/github', passport.authenticate('github', {
  scope:[ 'profile', 'id']
}));
router.get('/auth/github/callback', 
  passport.authenticate('github', { session:true, failureRedirect: 'http:localhost:8001/signIn' }),
  function(req, res) {
    // 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);
    // })
    const user = req.user
    req.logIn(user, err => {
      models.User.findOne({
         where: {
           id: req.user.id,
         },
       }).then(user => {
         const token = jwt.sign({ id: 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.redirect('http://localhost:8001');

         // console.log(req.user)
       });
     });

    console.log(`frontid ${req.user.id}`)
    // res.redirect('')
    // console.log('this works', token);
  });

护照-github.js

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);
// });
module.exports = async (passport) => {

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.findOne({
         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
  return 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
      .findOne({ where: { id: userId } })
      .then(function(user){
        // console.log(user);
       return  done(null, userId);
      }).catch(function(err){
        done(err, null);
      });
  // return done(null, id);
});


}

应用程序.js

const express = require('express');
const app = express();
const userRoute = require('./routes/users');
const postRoute  = require('./routes/posts');
const bodyParser = require('body-parser');
const logger = require('morgan');
const session = require('express-session');
const  cookieParser = require('cookie-parser') ;
const dotenv = require('dotenv');
const env = dotenv.config();
const cors = require('cors');
const models = require('./models/');
const host = '0.0.0.0';
const PORT = process.env.PORT || 8000;
const passport = require('passport');
const path = require('path');
const Sequelize = require('sequelize');
const SequelizeStore = require('connect-session-sequelize')(session.Store);
const proxy = require('express-http-proxy');

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();
});
app.use(cors({
  origin: process.env.ALLOW_ORIGIN,
  credentials: false,
  allowedHeaders: 'X-Requested-With, Content-Type, Authorization',
  methods: 'GET, POST, PATCH, PUT, POST, DELETE, OPTIONS',
  exposedHeaders: ['Content-Length', 'X-Foo', 'X-Bar'],
}))
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')));



// We need a store in order to save sessions, instead of the sessions clearing out on us :)

require('./config/passport')(passport); // PASSPORT Init
require('./config/passport-github')(passport); // PASSPORT Init
app.use(cookieParser());
app.use(bodyParser.json());
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();
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({ extended:false})); 


// this code may be useless or useful, still trying to understand cors. 

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

标签: node.jsexpresspassport.js

解决方案


推荐阅读