Express login session only lasts one page view

241 Views Asked by At

In the code below, when I visit / the first time (not logged onto FB) I'm redirected to the /login page, as expected.

Then I login onto facebook and I'm then taken to /, as expected

If I then refresh the page (while on /) I'm taken back the /login page, as if the session is already over.

It looks like for every new page view of / I'm always asked to login every time.

What am I doing wrong ?

(for testing purposes I'm not yet using a real database and have just set up this preliminary user.js one for the sake of the session..)

user.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
  }
}

server.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)
1

There are 1 best solutions below

1
Kawd On

It was because of nodemon.

Every time the user logs in I update some files and I forgot to tell nodemon to ignore those changes so the server restarts every time due to those file changes.

Whenever the server restarts the session is also reset.

Be careful with nodemon, make sure you place any files your server will be changing inside a folder and tell nodemon to ignore it.

On the other hand, a server might restart for other reasons as well. Why should the session be reset every time ? Isn't there a way around it ?.