Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose/Express authorisation on http verbs

I've got a node.js REST service running on mongoose and express. I'm also using merse to get my routing set up.

What I'd like to achieve now are the following types of sceanrios:

Scenario I: e.g. blogpost
- GET -> no authentication required
- POST/PUT/DELETE -> authentication required

Scenario II: e.g. user
- GET -> authentication required
- POST/PUT/DELETE -> authentication required plus username of logged in user has to match

I've allready had a look at everyauth and mongoose-auth, but couldn't find anything which would give me this kind of control.

like image 651
AyKarsi Avatar asked Dec 07 '22 13:12

AyKarsi


1 Answers

Forget about everyauth. This library is an overkill, imho. Implementing authentication is quite simple actually, follow the schema:

  1. User passes username and password to the server;
  2. Server gets username and password and checks in DB whether there is a user with that password. If there is no user, just respond with an error;
  3. We have a user, now use built-in session mechanism of Express. Call req.session.regenerate and in the callback do req.session.userID = user.id. Express will automatically send the cookie to the user;
  4. Create a middleware (has to fire before any other request handler), which basically searches the database for req.session.userID. If it finds one, then store it in req, i.e. req.user = user;
  5. In a view you simply check whether req.user variable is set. If it is, then we are authenticated. And you're done!

ad 1+2) To make authentication safe, you should use some cryptography (and/or HTTPS). For example, the password should be held in DB in two parts: salt and hash. salt is generated randomly (at the time of registration) and hash = hash_it(pwd, salt), where hash_it is some hashing algorithm (for example: MD5 or SHA256).

Now client side authentication can be made in several steps (only if you can use JavaScript):

  1. Server sends random new_salt to the login page (or generate one in JavaScript, there is no need to hide generating algorithm);
  2. User sends AJAX request give me salt for user X and server responds with the salt stored in DB (the salt is public);
  3. On response hash pwd with salt and then hash the result again with new_salt, store it in variable hpwd;
  4. Client sends username, hpwd and new_salt to the server;
  5. Server gets pwd from DB for username, hashes pwd with new_salt and compares the result to hpwd (note: you do not store new_salt).

This method is nice, since every time you log in a random (from the external point of view) data flows through net, even though the username and the password is the same.

This is important, because password leak is a serious thing. Not because someone can break your app's account (that's a minor damage, unless you're a bank - but then you wouldn't ask such questions :D ). Mostly because people tend to use the same passwords for multiple sites, including bank accounts.

like image 149
freakish Avatar answered Dec 09 '22 01:12

freakish