简体   繁体   中英

refactoring passport.js authentication code

We have a passport.js file like this:

const axios = require('axios')
const uuid = require('uuid/v4')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
const session = require('express-session')
const mongoStore = require('connect-mongo')(session)

module.exports = (app) => {
    const users = [
        {
            id: '2f24vvg',
            email: 'test@test.com',
            password: 'password'
        }
    ]

    const mongoSessionStore = new mongoStore({
        url: 'mongodb://localhost/test-app',
        ttl: 30 * 60 // 30 min
    })

    let sess = {
        genid: (req) => {
            console.log('Inside the session middleware')
            console.log(req.sessionID)
            return uuid()
        },
        store: mongoSessionStore,
        secret: 'keyboard cat', // password from environment
        resave: false,
        rolling: true,
        saveUninitialized: true,
        unset: 'destroy', // removes the session from the server when end() is called
        cookie: {
            HttpOnly: true,
            maxAge: 30 * 60 * 1000 // 30 minutes
        }
    }

    app.use(session(sess))

    passport.use(new LocalStrategy(
        { usernameField: 'email' },
        (email, password, done) => {
            axios.get(`http://localhost:5000/users?email=${email}`)
                .then(res => {
                    const user = res.data[0]
                    if (!user) {
                        return done(null, false, { message: 'Invalid credentials.\n' })
                    }
                    if (password != user.password) {
                        return done(null, false, { message: 'Invalid password.\n' })
                    }
                    return done(null, user)
                })
                .catch(error => done(error))
        }
    ))

    passport.serializeUser((user, done) => {
        console.log('Inside serializeUser callback. User id is saved to the session store')
        done(null, user.id)
    })
    passport.deserializeUser((id, done) => {
        axios.get(`http://localhost:5000/users/${id}`)
            .then(res => done(null, res.data))
            .catch(error => done(error, false))
    })

    app.use(passport.initialize())
    app.use(passport.session())
}

We have multiple router files that contain the same function isAuthorized :

function isAuthorized(req, res, next) {
    if (req.isAuthenticated()) {
        console.log('Is allowed')
        next()
    }
    else {
        console.log('Is not allowed')
        res.sendStatus(401)
        // res.redirect('/')
    }
}
// Example in use:
router.get('/secure', isAuthorized, (req, res) => {
    res.format({
        html: () => {
            res.render('secure')
        },

        json: () => {
            res.send({ message: 'you reached the secure endpoint' })
        }
    })
})

To avoid having the function isAuthorized in every routes.js file we're trying to move it to a module. For this I thought it would be sufficient to add it to the end of passport.js as following:

module.exports = function isAuthorized(req, res, next) {
    if (req.isAuthenticated()) {
        console.log('Is allowed')
        next()
    }
    else {
        console.log('Is not allowed')
        res.sendStatus(401)
        // res.redirect('/')
    }
}

However, when we then try to use it in the route.js files we get the error:

TypeError: req.isAuthenticated is not a function

How can this function be separate from the routes and still be used? Thank you for the help.

This is what your middleware function should look like

 module.exports = (req, res, next) => {

        if (req.Authenticated()) {
            return next();

        } else {

            res.status(401);
        }
    }

and this is how you use your middleware in other(ie server.js) files

    const theMiddleWare = "/middlewareDir";
    app.use("/routes",theMiddleWare(),"routeDir");
// before doing this you have to add the passport middleware

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM