I'm pretty new to MEAN stack applications and session flow itself. I have admin dashboard and certain API routes I want to protect to access only by an admin. Also I'm using socket.io with passport sessions stored in Redis Store and checking if user who emitted socket is authenticated and an admin. I'm granting admin rights in the following way: there is a MongoDB collection of users with certain boolean value "isAdmin".
When user authenticates we go:
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);
}
};
Then, if I want to protect any API route I'm going:
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
}
});
Here is how I'm passing session to 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);
});
Then, if I want to check if certain socket was emitted by an admin:
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;
}
};
And the socket event itself:
socket.on('someProtectedEvent', function(data) {
if(isAdmin(socket)) {
// User has rights to use this event
} else {
// User is not an admin
}
});
So, are my dashboard, routes and sensitive socket.io events protected enough? I mean, can anyone bypass these verifications in easy way, or just set this boolean "isAdmin" to true in their own session? Or am I going right way and my dashboard and admin-events are enough protected?
Thanks for your help in advance
via Danny
No comments:
Post a Comment