Login NodeJS

  • View

  • Download

Embed Size (px)

Text of Login NodeJS

Building a Login System in Node.js and MongoDBJune 4, 2012 Javascript | Node.js 62 Comments


This past week I finally got around to playing with Node.js and am really impressed with how simple it was to get a server and database up and running in literally minutes. Once there, I thought a good first project to explore the platform would be to try building a simple login system analogous to what I feel like Ive built a million times in mysql & php. So after thinking about it a bit, I knew these were the basic features I wanted to implement :

CategoriesActionscript / Flash General News Node.js Processing Arduino Javascript OpenFrameworks Python Travel

Login PanelJust a simple login panel with the ability to reset a lost password and of course the ability to create an account for first time users. An option to remember me that saves the users data in a local cookie allowing them to bypass the login screen whenever they revisit the site.

Raspberry PI Unix

Recent Twitter31 March 2013 at 10:45pm

Follow @braitsch


@sansumbrella will do, cheers mate!

@sansumbrella gotcha, thanks dude. really appreciate the nod. i was really scratching my head over this.31 March 2013 at 10:43pm

@sansumbrella ah thanks! question tho would that require every triangle to have unique vertices? even if they're in the same position?31 March 2013 at 10:40pm

Recent PostsControlling 24 LEDs with Node.js & a Raspberry PI How to Setup Node.js on a Raspberry PI Why Isnt Stylus Compiling my CSS? Internet Service Provider Health Monitor Building a Node.js Chat Application and Sharing Socket.IO Across Multiple Subdomains

New Account ScreenAsimple form that allows a new user to set their username & password, as well as some personal data such as their real name, email and location.

Popular Posts

converted by Web2PDFConvert.com

Transform Tool - Drag, Scale and Rotate in Flash at Runtime 66 comments Building a Login System in Node.js and MongoDB 62 comments Dynamically Create an Image in Flash and Save it to the Desktop or Server 56 comments

And Some Recent Snaps on Flickr...

Account Update ScreenAlmost identical to the account creation screen, with the slight modification that the username field is deactivated so it cannot be changed allowing us to preserve a unique key to identify each account. Here well also add a button that will allow users to delete their account.

Password RetrievalAsimple modal window where users can request an email to reset their password.

converted by Web2PDFConvert.com

If youd like to jump ahead : check out the full working version of the app or download and install the source code here

Standing on the Shoulders of GiantsOne of the most impressive highlights of the Node.js ecosystem in my opinion is the incredible myriad of libraries actively being produced to take much of the heavy lifting out of building your app. In our login system well leverage the following libraries to get us up and running : Express.js ANode.js framework with a ton of convenient features that make working in Node much faster MongoDb ANoSQL database well use to save our account data Jade Atemplating engine that allows us to write less verbose HTML Stylus ACSS-preprocessor with a zillion amazing features that greatly take the pain out of writing traditional CSS Email.js Middleware to easily dispatch emails from our Node.js server Moment.js Alightweight library for convenient date parsing & formatting And last but not least the inimitableTwitter Bootstrap UI library to layout our forms and pages with beauty and consistency across browsers.

Application StructureOur login system will of course need to execute code in two environments, on the client machine and on the server. On the client side well need to display our HTML pages, handle user interactions, and validate the various forms our app uses before sending their data to the server. On the server side well layout our HTML pages using Jade templates and create a few custom modules to read and write to the database and dispatch emails for password retrieval. The general layout of these two environments is as follows : Server-Side Components : views jade templates that compile to HTML login.jade home.jade signup.jade modules helper classes that interact with the database and dispatch emails account-manager.js email-dispatcher.js Client-Side Components : views these setup our form controllers & modal windows login.js home.js signup.js controllers handle user interactions loginController.js homeController.js signupController.js

converted by Web2PDFConvert.com

form-validators validate forms and display errors loginValidator.js accountValidator.js resetValidator.js emailValidator.js Note : Because the new account and update account forms are so similar, Ive consolidated the code that validates them into one file called AccountValidator and then put any code that differs between them in their respective controllers SignupController & HomeController.

So How Does All This Actually Work?The basic page flow can be generalized into two parts: Part 1 : Getting the Page 1. Auser arrives at http://node-login.braitsch.io/ and requests the root page or / 2. Router.js on our server sees this GET request and returns login.jade, the view associated with http://node-login.braitsch.io/ However before it does this, it checks the GET request object for a username & password cookie and if they exist and validate, redirects the browser to http://node-login.braitsch.io/home

var AM = require('./modules/account-manager'); app.get('/', function(req, res){ // check if the user's credentials are saved in a cookie // if (req.cookies.user == undefined || req.cookies.pass == undefined){res.render('login', { locals: { title: 'Hello - Please Login To Your Account' } } ); } else{

// attempt automatic login //AM.autoLogin(req.cookies.user, req.cookies.pass, function(o){ if (o != null){ req.session.user = o; res.redirect('/home'); } else{ res.render('login', { locals: { title: 'Hello - Please Login To Your Account' } } ); } }); } }); 3. Otherwise, the server renders login.jade into the HTML login form and sends it to the browser. 4. Once the HTML is received by the client, the script tags in the page request the JavaScript files associated with the login page, namely : /js/views/login.js /js/controllers/loginController.js /js/form-validators/loginValidator.js /js/form-validators/emailValidator.js 5. These four component files setup the form and alert windows, listen for user interaction and validate the form before sending it back to the server. Part 2 : Posting the Page 1. Auser enters their username & password and hits submit 2. loginValidator.js validates the form and then allows login.js to send its contents to the server as a POST request. 3. Router.js on the server sees the incoming POST request and forwards the username & password to the AccountManager module which compares what the user entered to the values stored in the database. Once Router.js gets a response from the AccountManager it either sends a 200 (pass) or 400 (fail) status code back to the browser.

var AM = require('./modules/account-manager'); var EM = require('./modules/email-dispatcher'); app.post('/', function(req, res){ if (req.param('email') != null){ AM.getEmail(req.param('email'), function(o){ if (o){res.send('ok', 200); EM.send(o, function(e, m){ console.log('error : '+e, 'msg : '+m)}); } else{

converted by Web2PDFConvert.com

res.send('email-not-found', 400); } }); } else{

// attempt manual login //AM.manualLogin(req.param('user'), req.param('pass'), function(e, o){ if (!o){ res.send(e, 400); }else{ req.session.user = o; if (req.param('remember-me') == 'true'){ res.cookie('user', o.user, { maxAge: 900000 }); res.cookie('pass', o.pass, { maxAge: 900000 }); } res.send(o, 200); } }); } }); 4. login.js which owns the login form, hears the returned value and either redirects the user to the logged in page, or shows an alert window that displays a specific error message.

var lv = new LoginValidator(); var lc = new LoginController(); // main login form //$('#login-form').ajaxForm({ beforeSubmit : function(formData, jqForm, options){ if (lv.validateForm() == false){ return false; } else{

// append 'remember-me' option to formData to write local cookie //formData.push({name:'remember-me', value:$("input:checkbox:checked").length == 1}) return true; } }, success : function(responseText, status, xhr, $form){ if (status == 'success') window.location.href = '/home'; }, error : function(e){ lv.showLoginError('Login Failure', 'Please check your username and/or password'); } });

This communication sequence between the server and the client is essentially what is happening on each page of our app. In Summary 1. The user arrives at a page 2. Router.js returns the appropriate Jade template that renders the pages HTML and loads its JavaScript controllers 3. The user interacts with the page typically by filling out and submitting a form 4. Some JavaScript validates the form and sends its data back to the server 5. Router.js forwards the data to the AccountManager for comparison, entry, deletion, etc. in the database 6. The AccountManger returns a pass or fail response back to Router.js which then gets sent back to the client 7. JavaScript on the client handles the response by either redirecting the browser or showing a modal window with a detailed response. As you can see the communication between the client and server is not terribly complicated however it does beg the question as to how to best organize this communication into components and modules. So with that in mind, the source for this app is fully available on github with ins