Home > Software design >  req.isAuthenticated is not a function while using Express and passport
req.isAuthenticated is not a function while using Express and passport

Time:11-17

in the last few hours I setup a backend express server. It works just fine and now I tryed to implement an authorization with help of a tutorial.

The login works, but when I try to open /authrequired (so basically a future page which needs a logged in user to work) I get the error message: "TypeError: req.isAuthenticated is not a function"

Here is my index.js file:

const express = require('express');
const fs = require('fs');
const http = require('http');
const https = require('https');
const path = require('path');
const uuid = require('uuid').v4;
const session = require('express-session');
const FileStore = require('session-file-store')(session);
const bodyParser = require('body-parser');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

const users = [
  {id: '2f24vvg', email: '[email protected]', password: 'password'}
]

// configure passport.js to use the local strategy
passport.use(new LocalStrategy(
  { usernameField: 'email' },
  (email, password, done) => {
    console.log('Inside local strategy callback')
    // here is where you make a call to the database
    // to find the user based on their username or email address
    // for now, we'll just pretend we found that it was users[0]
    const user = users[0] 
    if(email === user.email && password === user.password) {
      console.log('Local strategy returned true')
      return done(null, user)
    }
  }
));

// tell passport how to serialize the user
passport.serializeUser((user, done) => {
  console.log('Inside serializeUser callback. User id is save to the session file store here')
  done(null, user.id);
});

passport.deserializeUser((id, done) => {
  console.log('Inside deserializeUser callback')
  console.log(`The user id passport saved in the session file store is: ${id}`)
  const user = users[0].id === id ? users[0] : false; 
  done(null, user);
});

const app = express();

app.enable('trust proxy')

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.use(session({
  genid: (req) => {
    console.log('Inside the session middleware')
    console.log(req.sessionID)
    return uuid() // use UUIDs for session IDs
  },
  store: new FileStore(),
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true
}))

app.post('/login', (req, res, next) => {
  console.log('Inside POST /login callback')
  passport.authenticate('local', (err, user, info) => {
    console.log('Inside passport.authenticate() callback');
    console.log(`req.session.passport: ${JSON.stringify(req.session.passport)}`)
    console.log(`req.user: ${JSON.stringify(req.user)}`)
    req.login(user, (err) => {
      console.log('Inside req.login() callback')
      console.log(`req.session.passport: ${JSON.stringify(req.session.passport)}`)
      console.log(`req.user: ${JSON.stringify(req.user)}`)
      return res.send('You were authenticated & logged in!\n');
    })
  })(req, res, next);
})

app.get('/authrequired', (req, res) => {
  console.log('Inside GET /authrequired callback')
  console.log(`User authenticated? ${req.isAuthenticated()}`)
  if(req.isAuthenticated()) {
    res.send('you hit the authentication endpoint\n')
  } else {
    res.redirect('/')
  }
})

app.use(express.static(path.resolve(__dirname, 'build')));

app.use(express.json());

// Redirect from http port to https
http.createServer(function (req, res) {
  res.writeHead(301, { "Location": "https://"   req.headers['host'].replace(80,433)   req.url });
  console.log("http request, will go to >> ");
  console.log("https://"   req.headers['host'].replace(80,433)   req.url );
  res.end();
}).listen(80, () => console.info('Listening on port', 80))

//Start https server
https.createServer({
  key: fs.readFileSync('./ssl/privkey.key'),
  cert: fs.readFileSync('./ssl/cert.cer'),
  keepAlive: true
}, app).listen(443, () => console.info('Listening on port', 443));

Anyone got a clue? I saw similar questions on stackoverflow, but nothing worked for me.

CodePudding user response:

There is no such function isAuthenticated. That's why you get the error.

Try replace it with if(req.session.user) {

Or by the example in express-session

// middleware to test if authenticated
function isAuthenticated (req, res, next) {
  if (req.session.user) next()
  else next('route')
}

app.get('/', isAuthenticated, function (req, res) {
  // this is only called when there is an authentication user due to isAuthenticated
  res.send('hello, '   escapeHtml(req.session.user)   '!'  
    ' <a href="/logout">Logout</a>')
})

CodePudding user response:

So for everyone who is struggling with the same problem. Thanks to @yeya I found a solution which was working for me.

const express = require('express');
const fs = require('fs');
const http = require('http');
const https = require('https');
const path = require('path');
const uuid = require('uuid').v4;
const session = require('express-session');
const FileStore = require('session-file-store')(session);
const bodyParser = require('body-parser');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

const users = [
  {id: '2f24vvg', email: '[email protected]', password: 'password'}
]

// configure passport.js to use the local strategy
passport.use(new LocalStrategy(
  { usernameField: 'email' },
  (email, password, done) => {
    console.log('Inside local strategy callback')
    // here is where you make a call to the database
    // to find the user based on their username or email address
    // for now, we'll just pretend we found that it was users[0]
    const user = users[0] 
    if(email === user.email && password === user.password) {
      console.log('Local strategy returned true')
      return done(null, user)
    }
  }
));

// tell passport how to serialize the user
passport.serializeUser((user, done) => {
  console.log('Inside serializeUser callback. User id is save to the session file store here')
  done(null, user.id);
});

passport.deserializeUser((id, done) => {
  console.log('Inside deserializeUser callback')
  console.log(`The user id passport saved in the session file store is: ${id}`)
  const user = users[0].id === id ? users[0] : false; 
  done(null, user);
});

const app = express();

app.enable('trust proxy')

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.use(session({
  genid: (req) => {
    console.log('Inside the session middleware')
    console.log(req.sessionID)
    return uuid() // use UUIDs for session IDs
  },
  store: new FileStore(),
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true
}))

app.post('/login', (req, res, next) => {
  console.log('Inside POST /login callback')
  passport.authenticate('local', (err, user, info) => {
    console.log('Inside passport.authenticate() callback');
    console.log(`req.session.passport: ${JSON.stringify(req.session.passport)}`)
    console.log(`req.user: ${JSON.stringify(req.user)}`)
    req.login(user, (err) => {
      console.log('Inside req.login() callback')
      console.log(`req.session.passport: ${JSON.stringify(req.session.passport)}`)
      console.log(`req.user: ${JSON.stringify(req.user)}`)
      return res.send('You were authenticated & logged in!\n');
    })
  })(req, res, next);
})

function isAuthenticated (req, res, next) {
  if (req.session.passport.user) next()
  else next('route')
}

app.get('/authrequired', isAuthenticated, function (req, res) {
    res.send('you hit the authentication endpoint\n')
})

app.use(express.static(path.resolve(__dirname, 'build')));

app.use(express.json());

// Redirect from http port to https
http.createServer(function (req, res) {
  res.writeHead(301, { "Location": "https://"   req.headers['host'].replace(80,433)   req.url });
  console.log("http request, will go to >> ");
  console.log("https://"   req.headers['host'].replace(80,433)   req.url );
  res.end();
}).listen(80, () => console.info('Listening on port', 80))

//Start https server
https.createServer({
  key: fs.readFileSync('./ssl/privkey.key'),
  cert: fs.readFileSync('./ssl/cert.cer'),
  keepAlive: true
}, app).listen(443, () => console.info('Listening on port', 443));

As you can see, I defined a isAuthenticated function and called it in my app.get('/authrequired'). First this didn't worked for me, but after doing some console.logs I found out that req.session.user and req.user are undefined and that there is an passport object where I can grab the id of my user with req.session.passport.user.

I can't tell you if this is a good or secure solution. Would be very happy if a Pro sees this and gives me some feedback (kinda don't understand why there is a req.session but it is empty).

  • Related