We could implement user authentication and accounts by simply adding a user model, and a few routes and views to the existing Notes application. While it would be accomplishable, is this what we would do in a real-world production application?
Consider the high value of user identity information, and the super-strong need for robust and reliable user authentication. Website intrusions happen regularly, and it seems the item most frequently stolen is user identities.
Can you design and build a user authentication system with the required level of security? One that is probably safe against all kinds of intruders?
As with so many other software development problems, it's best to use a pre-existing authentication library, preferably one with a long track record, where significant bugs have been fixed already.
Another issue is architectural choices to promote security. Bugs will occur and the talented miscreants will break in. Walling off the user information database is an excellent idea to limit the risk.
Keeping a user information database enables you to authenticate your users, present user profiles, help users connect with each other, and so forth. Those are useful services to offer to website users, but how can you limit the risk that data will fall into the wrong hands?
In this chapter, we'll develop a user authentication microservice. The plan is to eventually segregate that service into a well-protected barricaded area. This mimics an architectural choice made by some sites, to strictly control API and even physical access to the user information database, implementing as many technological barriers as possible against unapproved access.
Microservices are, of course, not a panacea, meaning we shouldn't try to force-fit every application into the microservice box. By analogy, microservices are like the Unix philosophy of small tools each doing one thing well, which we mix/match/combine into larger tools. Another word for this is composability. While we can build a lot of useful software tools with that philosophy, does it work for applications such as Photoshop or LibreOffice? While composing a system out of single-purpose tools is highly flexible, one loses the advantages gained by tight integration of components.
The first question is whether to use a REST-service oriented framework, code the REST application on bare Node.js, or what? You could implement REST services on the built-in http module. The advantage of using an application framework is the framework authors will have already baked-in a lot of best practices and bug fixing and security measures. Express, for example, is widely used, very popular, and can easily be used for REST services. There are other frameworks more aligned with developing REST services, and we'll use one of them – Restify (http://restify.com/).
The user authentication server will require two modules:
- Using Restify, implementing the REST interface
- A data model using Sequelize to store user data objects in an SQL database
To test the service, we'll write a couple of simple scripts for administering user information in the database. We won't be implementing an administrative user interface in the Notes application, and will rely on the scripts to administer the users. As a side effect, we'll have a tool to run a couple of simple tests against the user service.
After this service is functioning correctly, we'll set about modifying the Notes application to access user information from the service, while using Passport to handle authentication.
The first step is creating a new directory to hold the User Information microservice. This should be a sibling directory to the Notes application. If you created a directory named chap08/notes to hold the Notes application, then create a directory named chap08/users to hold the microservice.
Then run the following commands:
$ cd users
$ npm init
.. answer questions
.. name - user-auth-server
$ npm install debug@^2.6.x fs-extra@^5.x js-yaml@^3.10.x \
restify@^6.3.x restify-clients@^1.5.x sequelize@^4.31.x \
sqlite3@^3.1.x --save
This gets us ready to start coding. We'll use the debug module for logging messages, js-yaml to read the Sequelize configuration file, restify for its REST framework, and sequelize/mysql/sqlite3 for database access.