首页 > 解决方案 > 快速登录会话仅持续一页视图

问题描述

在下面的代码中,当我/第一次访问(未登录 FB)时,我被重定向到该/login页面,正如预期的那样。

然后我登录到 facebook,然后我被带到了/,正如预期的那样

如果我然后刷新页面(在 上/),我将收回/login页面,就好像会话已经结束一样。

看起来每次新的页面浏览/都要求我每次登录。

我究竟做错了什么 ?

(出于测试目的,我还没有使用真正的数据库,只是为了会话而设置了这个初步的 user.js ..)

用户.js

import fs from 'fs'

if (!fs.existsSync('./user.json')) {
  fs.writeFileSync('./user.json', JSON.stringify(null))
}

export default {

  query(facebookId) {
    let user = JSON.parse(fs.readFileSync('./user.json', 'utf8'));

    if (user && user.facebookId === facebookId) {
      return user
    }

    return null
  },

  save(user) {
    fs.writeFileSync('./user.json', JSON.stringify(user, null, 2))
    return user
  },

  delete() {
    fs.writeFileSync('./user.json', JSON.stringify(null, null, 2))
    return true
  }
}

服务器.js

import { Strategy as FacebookStrategy } from 'passport-facebook'
import express                          from 'express'
import passport                         from 'passport'
import session                          from 'express-session'
import fetch                            from 'node-fetch'
import { fileURLToPath }                from 'url'
import { dirname }                      from 'path'
import cors                             from 'cors'
import cookieParser                     from 'cookie-parser'
import { ensureLoggedIn }               from 'connect-ensure-login'
import FB                               from './fb'
import USER                             from './user'
import bodyParser                       from 'body-parser'

const jsonParser = bodyParser.json()
    
const {
  PORT,
  INSTAGRAM_USER_ID,
  FACEBOOK_APP_ID,
  FACEBOOK_APP_SECRET,
  FACEBOOK_PAGE_NAME
} = process.env

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

const app = express()

app.use(cors({
   origin: '*',
   credentials: true,
   optionSuccessStatus: 200
}))

app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', `http://localhost:${PORT}`)
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization')
  res.header('Access-Control-Allow-Methods', 'POST, GET')
  next()
})

app.use(cookieParser())
app.use(bodyParser.json({limit: "50mb"}));
app.use(bodyParser.urlencoded({limit: "50mb", extended: true, parameterLimit:50000}))
app.use(session({ secret: 'googoogaga', resave: false, saveUninitialized: false }))
app.use(passport.initialize())
app.use(passport.session())

passport.use(new facebookStrategy({
  clientID        : FACEBOOK_APP_ID,
  clientSecret    : FACEBOOK_APP_SECRET,
  callbackURL     : `http://localhost:${PORT}/facebook/callback`,
  profileFields: ['id', 'displayName']

}, function(accessToken, refreshToken, profile, done) {

    let user = USER.query(profile.id)

    if (user) {
      return done(null, user)
    } else {
      user = USER.save({
        facebookId: profile.id,
        accessToken
      })
      return done(null, user);
    }

}));

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

passport.deserializeUser(function(user, done) {
    done(null, user);
});
    
app.get('/auth/facebook', passport.authenticate('facebook', { scope:'email,instagram_basic,pages_show_list' }));

app.get('/facebook/callback', passport.authenticate('facebook', {
  successRedirect : '/',
  failureRedirect : '/login'
}));

app.get('/login', (req,res) => {
  res.sendFile(__dirname + '/public/login.html');
})

app.get('/', ensureLoggedIn('/login'), (req,res) => {
  res.status(200).send({ user: req.user })
})

app.get('/logout', function(req, res){
  req.session.destroy(()=>{
    USER.delete()
    res.redirect('/login')
  })
})  

app.listen(PORT)

标签: node.jsexpresspassport.jsexpress-sessionpassport-facebook

解决方案


那是因为nodemon

每次用户登录时,我都会更新一些文件,但我忘了告诉nodemon忽略这些更改,因此服务器每次都会由于这些文件更改而重新启动。

每当服务器重新启动时,会话也会被重置。

小心nodemon,确保将服务器将要更改的所有文件放在文件夹中并告诉nodemon忽略它。

另一方面,服务器也可能由于其他原因重新启动。为什么每次都要重置会话?没有办法解决吗?


推荐阅读