护照使用NextJs和Express对每个请求调用deserializeUser

时间:2019-09-23 20:56:54

标签: node.js express authentication passport.js next.js

我正在使用Passport Local,Express,Next.js和MongoSession存储为我的节点应用实现简单的登录。

一切正常,除了我的应用针对每个单个请求运行deserializeUser。这导致我的数据库在任何应用交互中都被击中10次以上

基于这篇文章https://github.com/jaredhanson/passport/issues/14#issuecomment-4863459,我知道我对静态资产的要求正在达到中间件堆栈。

大多数请求都针对路径/ _next / static *

如上例所示,我尝试实现express.static失败。请帮我弄清楚如何避免在每个请求上都调用deserializeUser。

谢谢!

这是我的代码:

app.js

const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(async () => {
  const server = express();
  server.use(helmet());
  server.use(express.static(path.join(__dirname, '_next', 'static')));
  server.use(express.json());

  auth({ ROOT_URL, server });
  api(server);

  routesWithSlug({ server, app });
  sitemapAndRobots({ server });

  server.get('*', (req, res) => {
    const url = URL_MAP[req.path];
    if (url) {
      app.render(req, res, url);
    } else {
      handle(req, res);
    }
  });

  server.listen(port, (err) => {
    if (err) throw err;
    logger.info(`> Ready on ${ROOT_URL}`);
  });
});

module.exports = { app };

auth.js

function auth({ ROOT_URL, server }) {
  const dev = process.env.NODE_ENV !== 'production';


  const MongoStore = mongoSessionStore(session);

  const sess = {
    name: 'builderbook.sid',
    secret: process.env.sessSecret,
    store: new MongoStore({
      mongooseConnection: mongoose.connection,
      ttl: 14 * 24 * 60 * 60, // expires in 14 days
    }),
    resave: false,
    saveUninitialized: false,
    cookie: {
      httpOnly: true,
      maxAge: 14 * 24 * 60 * 60 * 1000, // expires in 14 days
    },
  };

  if (!dev) {
    server.set('trust proxy', 1);
    sess.cookie.secure = true;
  }

  server.use(session(sess));
  server.use(passport.initialize());
  server.use(passport.session());
  server.use(bodyParser.urlencoded({ extended: false }));

  passport.serializeUser((user, done) => {
    console.log('serializeUser');
    done(null, user.id);
  });

  passport.deserializeUser((id, done) => {
    console.log(`deserializeUser, id: ${id}`);
    User.findById(id, User.publicFields(), (err, user) => {
      done(err, user);
    });
  });

  const verifyLocal = async (req, email, password, done) => {
    console.log({ email, password, req });
    const { firstName, lastName } = req.body;
    try {
      // signInOrSign up the user to MongoDb
      const user = await User.signInOrSignUp({
        email,
        password,
        firstName,
        lastName,
      });
      console.log(user);

      if (!user) {
        return done(null, false);
      }

      if (!User.verifyPassword(email, password)) {
        return done(null, false);
      }
      return done(null, user);
    } catch (err) {
      console.log(err); // eslint-disable-line
      return done(err);
    }
  };


  passport.use(
    new LocalStrategy(
      {
        usernameField: 'email',
        passReqToCallback: true,
      },
      verifyLocal,
    ),
  );
}

module.exports = auth;

authroutes.js

router.post('/login', passport.authenticate('local', { failureRedirect: '/fail' }), (req, res) => {
  res.redirect('/');
});

router.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/login');
});

module.exports = router;

1 个答案:

答案 0 :(得分:1)

这段代码似乎可以解决问题。感谢Tima在Builderbook上的帮助!

https://github.com/builderbook/builderbook/issues/229

server.get('/_next*', (req, res) => {
    handle(req, res);
  });

  server.get('/static/*', (req, res) => {
    handle(req, res);
  });