Wednesday 23 August 2017

Sessions and OAuth to Authorize and Authenticate Users in Node.js Apps

Authentication and Authorization
Authentication is the process of ascertaining that somebody really is who he claims to be.
Authorization refers to rules that determine who is allowed to do what. E.g. Adam may be authorized to create and delete databases, while Usama is only authorised to read.


 Authorization with Express.js middleware
 Token-based authentication
 Session-based authentication

  • Authorization with Express.js Middleware

Express.js middleware allows us to apply certain rules seamlessly to all routes, groups of routes (namespacing), or individual routes.

For example, if we want to protect all /api/ endpoints, we execute the following:
app.all('/api/*', auth);
app.get('/api/users', users.list);
app.post('/api/users', users.create);
...
Another way of doing the same thing is to execute:
app.get('/api/users', auth, users.list);
app.post('/api/users', auth, users.create);



In the above examples, auth() is a function with three parameters: req, res, and next—for example,
var auth = function(req, res, next) {
//authorize user
//if auth failed, then exit is next(new Error('Not authorized'));
//or res.send(401);
return next();
}

  • Token-Based Authentication
The most common authentication is a cookie & session–based authentication. However, in some cases, more REST-fulness is required, or cookies/sessions are not supported well
(e.g., mobile). In this case, it’s beneficial to authenticate each request with a token (probably using the OAuth2.0).


token-based authentication, each request can submit a token in a query string (accessed via
req.query.token). And, if we have the correct value stored somewhere in our app (database, or in this example just a
constant SECRET_TOKEN), we can check the incoming token against it. If the token matches our records, we call next()
to proceed with the request executions, if not then we call next(error) which triggers Express.js error handlers
execution (see the note below):


var auth = function(req, res, next) {
if (req.query.token && token === SECRET_TOKEN) {
// Client is fine, proceed to the next route
return next();
} else {
return next(new Error('Not authorized'));
// or res.send(401);
}
};

In a more realistic example, we use API keys and secrets to generate HMAC-SHA1 (hash-based message authentication code-secure hash algorithm strings, then compare them with the value in req.query.token.


  • Session-Based Authentication
The session-based method is the recommended way for basic web apps,
because browsers already know what to do with session headers.

var cookieParser = require('cookie-parser');
var session = require('express-session');
...
app.use(cookieParser());
app.use(session());

The rest is trivial; we can store any data in req.session and it appears automagically on each request from the
same client (assuming their browser supports cookies). Hence, the authentication consists of a route that stores some
flag (true/false) in the session and of an authorization function in which we check for that flag (if true, then proceed;
otherwise, exit). For example,

app.post('/login', function(req, res, next) {
// This function checks for credentials
// passed in the request's payload
if (checkForCredentials(req)) {
req.session.auth = true;
res.redirect('/dashboard'); // Private resource
} else {
res.send(401); // Not authorized
}
}); 

Avoid storing any sensitive information in cookies. The best practice is not to store any info in cookies
manually—except session ID, which Express.js middleware stores for us automatically—because cookies are not secure.
Also, cookies have a size limitation (depending on the browser, with Internet Explore being the stringiest) that is very easy
to reach.

By default, Express.js uses in-memory session storage. This means that every time an app is restarted or crashes,
the sessions are wiped out. To make sessions persistent and available across multiple servers, we can use Redis or MongoDB as session restore.

  • Node.js OAuth
It’s a module that generates signatures, encryptions, and HTTP headers, and makes requests.It is recommended that node-auth be used when complex integration is needed or when only certain pieces of OAuth are needed (e.g., header signatures are generated by node-auth, but the request is made by the superagent library).

Command to add OAuth to packaage.json:

$ npm install oauth@0.9.11 --save

Twitter uses OAuth2.0 for the so called app-only authorizations which are requests to protected resources.




No comments:

Post a Comment

Extract error records while inserting into db table using JDBCIO apache beam in java

 I was inserting data into postgres db using apache beam pipeline. it works perfectly with JdbcIO write of apache beam library. But, now, i ...