使用Redis Store会话变量保护NodeJS路由是否安全?

时间:2017-05-06 23:00:48

标签: node.js express redis socket.io passport.js

我对MEAN堆栈应用程序和会话流本身很新。我有管理仪表板和我想保护的某些API路由只能由管理员访问。此外,我还使用socket.io与存储在Redis Store中的护照会话,并检查发出套接字的用户是否经过身份验证和管理员。我通过以下方式授予管理员权限:MongoDB用户集合具有某些布尔值" isAdmin"。

当用户进行身份验证时,我们会:

db.users.findOne({ userID: profile.id }, function(err, user) {
    if (user) {
       // blah-blah-blah
       returnSession(user.isAdmin);
    }
});

function returnSession(isAdmin) {
    if(isAdmin) {
        profile.isAdmin = true;
        return done(null, profile);
    } else {
        return done(null, profile);
    }
};

然后,如果我想保护任何API路线,我会去:

function isAdmin (req) {
    if (req.isAuthenticated() && req.user.isAdmin) {
        return true;
    } else {
        return false;
    }
}

router.get('/test', function(req, res){
    if(isAdmin(req)) {
        // This user has access
    } else {
        // User is not an admin
    }
});

以下是我如何将会话传递给socket.io:

var sessionMW = session({
    store: new RedisStore({ host: 'localhost', port: 6397, client: redis}),
    secret: 'blah-blah', // my secret key to hash sessions
    name: 'nameOfCookie',
    resave: true,
    saveUninitialized: true
});

var app = express();
// ...
app.use(sessionMW);
// ...
app.use(passport.initialize());
app.use(passport.session());
// ...
//Body parser MW
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
// ...
passport.session();
//...
io.use(function(socket, next) {
    // Wrap the express middleware
    sessionMW(socket.request, {}, next);
});

然后,如果我想检查管理员是否发出了某个套接字:

function isAuthenticated(socket) {
    if(socket.request.session.hasOwnProperty('passport') && socket.request.session.passport.hasOwnProperty('user')) {
        return true;
    } else {
        return false;
    }
};
function isAdmin(socket) {
    if(socket.request.session.hasOwnProperty('passport') && socket.request.session.passport.hasOwnProperty('user')) {
        if(socket.request.session.passport.user.hasOwnProperty('isAdmin')) {
            return socket.request.session.passport.user.isAdmin;
        } else {
            return false;
        }
    } else {
        return false;
    }
};

套接字事件本身:

socket.on('someProtectedEvent', function(data) {
    if(isAdmin(socket)) {
        // User has rights to use this event
    } else {
        // User is not an admin
    }
});

据我所知,快递商店只在cookie中散列会话ID,然后将该id与我的Redis商店中的数据相匹配,这意味着我应该是安全的,因为潜在的入侵者并不知道我的秘密关键,对吗?主要问题是关于套接字事件保护。

那么,我的仪表板,路由和敏感的socket.io事件是否受到足够的保护?

感谢您的提前帮助

0 个答案:

没有答案