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