рефакторинг паспорта. js код аутентификации - PullRequest
0 голосов
/ 19 февраля 2020

У нас есть passport.js файл, подобный этому:

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())
}

У нас есть несколько файлов маршрутизатора, которые содержат одну и ту же функцию 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' })
        }
    })
})

Чтобы избежать использования функции isAuthorized в каждом файле routes.js мы пытаемся переместить его в модуль. Для этого я подумал, что было бы достаточно добавить его в конец passport.js следующим образом:

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('/')
    }
}

Однако, когда мы затем пытаемся использовать его в файлах route.js, мы получаем ошибку:

Ошибка типа: req.isAuthenticated не является функцией

Как эта функция может быть отделена от маршрутов и все еще использоваться? Спасибо вам за помощь.

1 Ответ

1 голос
/ 19 февраля 2020

Вот как должна выглядеть ваша функция промежуточного программного обеспечения

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

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

        } else {

            res.status(401);
        }
    }

, и именно так вы используете свое промежуточное программное обеспечение в других (т. Е. Серверных. js) файлах

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