javascript - In Node.js using Express, how does one have a user login along with admin login? I want users limited access with a

I built out a Node app with a user login and all the routes are protected for only users. Now I'd

I built out a Node app with a user login and all the routes are protected for only users. Now I'd like to take that a step further and have one login for users and admin, but once logged in the user has access to particular routes while the admin has access to all. Here's a snippet of what I currently have:

const express = require('express');
const app = express();
const session = require('express-session');
const pgSession = require('connect-pg-simple')(session);
const bodyParser = require('body-parser');

app.use(session({
    store: new pgSession({
        pgPromise: db
    }),
    secret: 'abc123',
    resave: false,
    saveUninitialized: false,
    cookie: {
        maxAge: 30 * 24 * 60 * 60 * 1000 
    }
}));

app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

// protected route function for all users
function protectRoute(req, res, next) {
    let isLoggedIn = req.session.user ? true : false;
    if (isLoggedIn) {
        next();
    } else {
        res.redirect('/search')
    }
}

//middleware
app.use((req, res, next) => {
    let isLoggedIn = req.session.user ? true : false; 
    next();
});

//login
app.get('/login', (req, res) => {
    res.send(page(loginForm()));
})

app.post('/login', (req, res) => {
    const theUsername = req.body.username;
    const thePassword = req.body.password;

    User.getUserByUsername(theUsername)
        .catch(err => {
            console.log(err);
            res.redirect('/login');
        })
        .then(theUser => {
            if(theUser.password === thePassword){
                req.session.user = theUser;
                req.session.save(function(err){
                    res.redirect('/search');
                });
            } else {
                res.redirect('/login');
            }
        })

})

// search page for all users and admin
app.get('/search', protectRoute, (req, res) => {
    res.send(page(panySearchForm(), req.session.user));
});

// inactive list that I WANT FOR ONLY ADMIN but currently for all users
app.get('/inactivelist', protectRoute, (req, res) => {
    Company.getCompanyByStatus(false)
        .catch(err => {
            console.log(err);
        })
        .then(theCompany => {
            const panyInfo = inactiveList(theCompany);
            const thePage = page(panyInfo, req.session.user);
            res.send(thePage);
        })
}) 

Here's the page view function that checks if loggedIn

const {logoutButton, loginOrRegister} = require('./helper');

function page(content, isLoggedIn=false){
    return `
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">

        <link rel="stylesheet" href="/stylesheets/index.css">

        <title>Document</title>
    </head>
    <body>
        ${
            isLoggedIn ? logoutButton() : loginOrRegister()
        }
        <div>
            ${content}
        </div>
    </body>
    </html>
    `
}

module.exports = page;

So as you can see all users have access to all protected routes. How would I make that so users get access to certain paths and admins have access to all? In my PostgreSQL database there's a column on users that's admin_access boolean default 'FALSE'. Here's the database users table schema:

create table users (
    id serial primary key,
    name text,
    username text,
    password text,
    admin_access boolean default 'FALSE'
);

I know it's a lot but I'd appreciate the help. No clue how admin access would work.

I built out a Node app with a user login and all the routes are protected for only users. Now I'd like to take that a step further and have one login for users and admin, but once logged in the user has access to particular routes while the admin has access to all. Here's a snippet of what I currently have:

const express = require('express');
const app = express();
const session = require('express-session');
const pgSession = require('connect-pg-simple')(session);
const bodyParser = require('body-parser');

app.use(session({
    store: new pgSession({
        pgPromise: db
    }),
    secret: 'abc123',
    resave: false,
    saveUninitialized: false,
    cookie: {
        maxAge: 30 * 24 * 60 * 60 * 1000 
    }
}));

app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

// protected route function for all users
function protectRoute(req, res, next) {
    let isLoggedIn = req.session.user ? true : false;
    if (isLoggedIn) {
        next();
    } else {
        res.redirect('/search')
    }
}

//middleware
app.use((req, res, next) => {
    let isLoggedIn = req.session.user ? true : false; 
    next();
});

//login
app.get('/login', (req, res) => {
    res.send(page(loginForm()));
})

app.post('/login', (req, res) => {
    const theUsername = req.body.username;
    const thePassword = req.body.password;

    User.getUserByUsername(theUsername)
        .catch(err => {
            console.log(err);
            res.redirect('/login');
        })
        .then(theUser => {
            if(theUser.password === thePassword){
                req.session.user = theUser;
                req.session.save(function(err){
                    res.redirect('/search');
                });
            } else {
                res.redirect('/login');
            }
        })

})

// search page for all users and admin
app.get('/search', protectRoute, (req, res) => {
    res.send(page(panySearchForm(), req.session.user));
});

// inactive list that I WANT FOR ONLY ADMIN but currently for all users
app.get('/inactivelist', protectRoute, (req, res) => {
    Company.getCompanyByStatus(false)
        .catch(err => {
            console.log(err);
        })
        .then(theCompany => {
            const panyInfo = inactiveList(theCompany);
            const thePage = page(panyInfo, req.session.user);
            res.send(thePage);
        })
}) 

Here's the page view function that checks if loggedIn

const {logoutButton, loginOrRegister} = require('./helper');

function page(content, isLoggedIn=false){
    return `
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">

        <link rel="stylesheet" href="/stylesheets/index.css">

        <title>Document</title>
    </head>
    <body>
        ${
            isLoggedIn ? logoutButton() : loginOrRegister()
        }
        <div>
            ${content}
        </div>
    </body>
    </html>
    `
}

module.exports = page;

So as you can see all users have access to all protected routes. How would I make that so users get access to certain paths and admins have access to all? In my PostgreSQL database there's a column on users that's admin_access boolean default 'FALSE'. Here's the database users table schema:

create table users (
    id serial primary key,
    name text,
    username text,
    password text,
    admin_access boolean default 'FALSE'
);

I know it's a lot but I'd appreciate the help. No clue how admin access would work.

Share Improve this question asked Dec 4, 2019 at 16:39 KllicksKllicks 1011 silver badge11 bronze badges 1
  • 1. during login processing: req.session.admin = theUser.admin_access;, this way you can check the user level at any point 2. whenever you're rendering a page or making a database operation, check req.session.admin first. You have all this in place already, since you're using the exact same mechanism to do the login check. (btw, try using a template engine like pug instead of sending back cobbled together HTML, it makes things a lot easier and smoother) – user5734311 Commented Dec 4, 2019 at 16:46
Add a ment  | 

2 Answers 2

Reset to default 6

I would use another middleware function such as the following

function isAdmin(req, res, next) {
    // Check if the requesting user is marked as admin in database
    let isAdmin = // check in database
    if (isAdmin) {
        next();
    } else {
        res.redirect('/search')
    }
}

and then I'd use it this way

// inactive list that I WANT FOR ONLY ADMIN but currently for all users
app.get('/inactivelist', protectRoute, isAdmin, (req, res) => {
    Company.getCompanyByStatus(false)
        .catch(err => {
            console.log(err);
        })
        .then(theCompany => {
            const panyInfo = inactiveList(theCompany);
            const thePage = page(panyInfo, req.session.user);
            res.send(thePage);
        })
}) 

for every route that actually requires you being an admin in order to use it

exports.restrictTo = (...roles) => {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({
        status : 'fail',
        message : 'You dont have permession'
      });
    }
    next();
  };
};

In the route file call it as middleware

const express = require('express');
const userController = require('./../controllers/userController');
const { protect ,restrictTo} = require('./../controllers/authController');

const router = express.Router();


router
  .route('/')
  .post( protect , restrictTo("admin") ,userController.createUser);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744215004a4563511.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信