Building a Login System in Node.

js and MongoDB
June 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 I’ve 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 :

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

Login Panel
Just 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 user’s data in a local cookie allowing them to bypass the login screen whenever they revisit the site.

Raspberry PI Unix

Recent Twitter
31 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 Posts
Controlling 24 LEDs with Node.js & a Raspberry PI How to Setup Node.js on a Raspberry PI Why Isn’t Stylus Compiling my CSS? Internet Service Provider Health Monitor Building a Node.js Chat Application and Sharing Socket.IO Across Multiple Subdomains

New Account Screen
Asimple 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

com . Scale and Rotate in Flash at Runtime • 66 comments Building a Login System in Node. converted by Web2PDFConvert.Drag. Account Update Screen Almost identical to the account creation screen. Here we’ll also add a button that will allow user’s to delete their account.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. 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.. Password Retrieval Asimple modal window where users can request an email to reset their password..Transform Tool .

js controllers – handle user interactions loginController. on the client machine and on the . Application Structure Our login system will of course need to execute code in two environments.js – Middleware to easily dispatch emails from our Node.js home.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.jade home.js framework with a ton of convenient features that make working in Node much faster MongoDb – ANoSQL database we’ll 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. On the client side we’ll need to display our HTML pages. handle user interactions.js – ANode.js signupController.js Client-Side Components : views – these setup our form controllers & modal windows login.jade signup. The general layout of these two environments is as follows : Server-Side Components : views – jade templates that compile to HTML login.js converted by Web2PDFConvert.js email-dispatcher.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 we’ll leverage the following libraries to get us up and running : Express.js server Moment.js signup.jade modules – helper classes that interact with the database and dispatch emails account-manager. On the server side we’ll 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.js homeController.If you’d 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 Giants One of the most impressive highlights of the Node. and validate the various forms our app uses before sending their data to the server.

Otherwise. } }). Part 2 : Posting the Page 1. 'msg : '+m)}).log('error : '+e. function(req. app. loginValidator.getEmail(req.cookies.render('login'. function(o){ if (o){ res.jade’. Router.js accountValidator.param('email') != null){ AM. Once the HTML is received by the client. function(e. { locals: { title: 'Hello .js to send its contents to the server as a POST and requests the root page or “/” 2.js Note : Because the new account and update account forms are so similar.js emailValidator. } else{ res. I’ve 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.user = o.jade into the HTML login form and sends it to the browser.js validates the form and then allows login. app. function(o){ if (o != null){ req. Once Router.js gets a response from the AccountManager it either sends a 200 (pass) or 400 (fail) status code back to the browser.send('ok'.pass.send(o.get('/'.post('/'. 3. res){ if (req. } else{ // attempt automatic login // AM. redirects the browser to http://node-login.cookies.form-validators – validate forms and display errors loginValidator./modules/account-manager'). the view associated with http://node-login.render('login'.cookies.user.braitsch. Router.js on our server sees this GET request and returns ‘login. 3. var AM = require('.com .js 5. So How Does All This Actually Work? The basic page flow can be generalized into two parts: Part 1 : Getting the Page 1. However before it does this.autoLogin(req. the script tags in the page request the JavaScript files associated with the login page. } else{ converted by Web2PDFConvert. 200). Auser arrives at http://node-login.js resetValidator.param('email'). namely : /js/views/login. 4.js /js/form-validators/emailValidator.cookies.braitsch.pass == undefined){ res. var EM = require('. listen for user interaction and validate the form before sending it back to the server. { locals: { title: 'Hello . Auser enters their username & password and hits “submit” 2.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.session. the server renders login./modules/email-dispatcher'). m){ console.redirect('/home'). res. EM. it checks the GET request object for a username & password cookie and if they exist and validate.Please Login To Your Account' } } ).Please Login To Your Account' } } ). These four component files setup the form and alert windows. } }). res){ // check if the user's credentials are saved in a cookie // if (req. function(req.user == undefined || req.js /js/form-validators/loginValidator.braitsch.js /js/controllers/loginController./modules/account-manager').io/home var AM = require('.

Router. etc. } }).href = '/home'. The user arrives at a page 2. } res.js returns the appropriate Jade template that renders the page’s HTML and loads its JavaScript controllers 3.res.send(o. 4. In Summary 1.length == 1}) return true. jqForm.send(e. req.location. the source for this app is fully available on github with instructions on how to install and get this running on your local machine. }.param('remember-me') == 'true'){ res. function(e. 400). o. in the database 6. }else{ req. The user interacts with the page typically by filling out and submitting a form 4.ajaxForm({ beforeSubmit : function(formData. options){ if (lv. var lc = new LoginController(). success : function(responseText.showLoginError('Login Failure'. } }). The AccountManger returns a pass or fail response back to Router. } }). o.user. o){ if (!o){ res. or shows an alert window that displays a specific error message. error : function(e){ lv. if (req.manualLogin(req.cookie('pass'.js which owns the login form. deletion. .js forwards the data to the AccountManager for comparison. value:$("input:checkbox:checked").param('user'). entry.validateForm() == false){ return false. 200). var lv = new LoginValidator(). questions and suggestions for improvement are most welcome. } }). Some JavaScript validates the form and sends its data back to the server 5. 'Please check your username and/or password').send('email-not-found'. } else{ // append 'remember-me' option to formData to write local cookie // formData.param('pass').user = o.session. Router.pass. 400). This communication sequence between the server and the client is essentially what is happening on each page of our app. xhr.cookie('user'.push({name:'remember-me'. login. 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. $form){ if (status == 'success') window. { maxAge: 900000 }). So with that in mind. // main login form // $('#login-form'). JavaScript on the client handles the response by either redirecting the browser or showing a modal window with a detailed response. hears the returned value and either redirects the user to the logged in page. } else{ // attempt manual login // AM. { maxAge: 900000 }). res. } }.js which then gets sent back to the client 7. ALSO ON THE CHOREOGRAPHY OF COLOR AND CODE AROUND THE WEB How to Drain Liquid From Behind the Ear Drum What Food To Avoid If You Have Acid Reflux VIDEO: Path To The Pros 2013: Montee Ball Are You Forgetting converted by Web2PDFConvert. As always feedback.

root + '/app/server')).use(exp.1 0 • Reply • Share › Mulyana • 6 months ago Stephen. 2. Declan 3 1 • Reply • Share › hugozap 1 • • 3 months ago Why is app. with CSS dictating where the login link is. and the jquery/javascript file is a simple lightbox type idea. converted by . exp)? It looks like you are passing app and exp to the require call but after looking at the node API I am at a loss.3. required? Doesn't it expose the server folder contents? Reply • Share › braitsch Mod hugozap • 3 months ago You're right that does and was a security vulnerability. But I have some questions. so that it translates into a native mongodb ISODate structure. had to start mongodb before running node app Reply • Share › bren101 • 3 months ago Two small suggestions: 1. and less lines of code as a bonus.0.x? Thanks for nice tutorial :) 1 • Reply • Share › braitsch Mod 0 • Mulyana • 3 months ago • Updated to express.2. Best Community Andrew Eremenko • 2 months ago Thank you for this great app. Sorry to post again but I have one more question. Those files have since been moved to /public/vendor as of v1. Write the time/date to mongodb as a native Date() object. Upgrade to bcrypt for more robust salt & hash quality..6 as of v1.Consumer Car Reviews 61 comments Leave a message. Can you explain what you are doing with this call: require('.0 Reply Share › Bryan Nichols • 7 months ago Stephen.js v3. Another question for you. My system is a simple html page.static(app. But I'm lost applying this to your project! How would I go about re-creating something similar without bootstrap. isn't it? How about idea to make auth token (or whatever) like at twitter or facebook? 18 • Reply • Share › Donald Trap 5 • • 5 months ago figured it out. 2 • Reply • Share › Declan E. It was there to allow access to vendor libs that were in /server/vendor. do you have any hints to get these login systems to work under Express 3. it's rather confusing for a newbie! Thanks again. Why did you store login and password in cookies? It's not secure. and for anyone new to using node/jade I'm finding it quite difficult to apply the logic and workings of your project to a simple login system I'm trying to make. I see you have used Bootstrap./app/config')(app.. • 5 months ago Hi.

. Do you have any recommendations for learning Node or JS in general? I've got a few books on it.e. I am really floored by the exceptional organization of it all. Reply • Share › tylerh 0 • 3 months ago This is sweet thanks for posting this! • Reply • Share › converted by Web2PDFConvert..exe with which to start the server.all needed exe's are there and I can start the server db and the shell. I was testing the app out on localhost and tried a password rest. Hard as I am a beginner. {safe: false}.else I would have done the update via GIT. In Part 2 point 2 loginValidator. the 'sever' folder of the app fail when trying to 'require' mongodb ( require ('mongodb'). callback). {safe: false}.I just want to say that not only is this an awesome project.. :) 0 • Reply • Share › Etna Mianuloe • 2 months ago Thanks for tutorial!! Trying to figure it out.if I install mongodb with npm. Originally it was this: accounts. it'd be great if you posted a link here so we can check it out.js? 0 • Reply • Share › Mark Barton • 2 months ago Hi..js to send its contents to the server as a POST request.on the updatePassword method in the account-manager.blah blah I noticed your website did not have the smtp notification setup too. One thing . Thanks so much! 1 • Reply • Share › Stephen Braitsch • 9 months ago Hi Tara.db 0 • Reply • Share › Alex • 2 months ago Thanks for this practical call i. Feel free to use the code in any way you . Great example . Thanks for sharing. Many thanks in advance..a mongodb folder is created in node_modules that has no bin folder and no mongodb.. I could not reset my password successfully with the message "I'm sorry something went wrong. 1 • Reply • Share › John F Dutcher • a month ago It's such a nice you foresee any issues? Thanks Mark 0 • Reply • Share › Eric Fleischmann 0 • • 2 months ago This is righteous. I added the account object so something was returned back to the callng method. But oddly.. what could be wrong here? On the node app.thanks.exe or mongo. I couldnt get it to return a HTTP 200 unless I amended the callback which was within the account. I am going to have a go at using mongoose as a learning exercise . thanks for asking. If I replace the mongodb folder in node_modules with an empty one and unzip the windows download from mongodb web site into it.js screen: TypeError: Cannot read property 'email' of undefined . please try again. Otherwise I've imposed no restrictions on how you can use this code.js validates the form and then allows login. What's the code for it in login.js file. callback(o)). Enjoy. I am new to node so I wasnt sure if this was correct . If you wind up using it in a public facing project." Assuming i have configured my smtp server setting correctly. I wanted to better understand how you segregated everything because it makes the project so much more organized. I am trying to build my first Node app and this gives me something to strive for. accounts. but i am finding that even the ones published last month have out of date source code due to the momentum of Node. Will try to get it to work with mongoose and bcrypt for my application.

io is a very easy to work with. Can you point me in the right direction on where to start troubleshooting this? Thanks in advance and thanks for this example.js to point to my smtp server with my credentials. WaltDjr 0 • Reply • Share › Tim Coombs 0 • • 4 months ago Great use of nodejs and jade. If you wanted to protect against something say like a SQL injection you'd want to add that sanitization in the AccountManager before allowing a write to the DB.bren101 0 • 3 months ago For security.braitsch. what are you talking about? Reply Share › bren101 braitsch • 3 months ago I'm talking about all the code in form-validators. how easy would it be to update/ edit it to have it work with socket. Great Thank you for you advice. I am in the process of creating a new site with a user account aspect but will be using you are not using it.jade use for ? • Reply • Share › Jube • 3 months ago Hello Braitsch. but now after a couple days of developing i can't not use it! Reply • Share › Mark Coles • 4 months ago Hi Stephen I like the example. doesn't it mean the server might do things such as write invalid email addresses into its database? 0 • Reply • Share › braitsch Mod bren101 • 3 months ago Ah yes I see what you're talking about. very clear and easy to follow. As a beginner I am not sure how did you host it in http://node-login. errno: 'ENOTFOUND'. 0 • Reply • Share › flo 0 • 3 months ago Tank's for sharing such great dev. Here's another project I wrote that shows how to setup a simple chat application using it. shouldn't the validation code really be running on the . I hadn't heard of jade. I'm fairly new to node and everything is working great except the "Forgot your --Jube 0 • Reply • Share › WaltDjr • 3 months ago Hi Stephen. It will definitely help get my feet wet in Node and Mongo along with the other modules you have used.jade and account. not the client? • Reply • Share › braitsch Mod 0 • bren101 • 3 months ago • Authentication is happening on the server. but if a malicious user bypasses the client-side validation. I've searched on this error and I'm not really finding anything. 0 • Reply • Share › JOhn terry • 5 months ago converted by Web2PDFConvert. Sure the client side validation just attempts to protect against common user errors such as an invalid email or empty form field." error : code 5 error : previous { [Error: getaddrinfo ENOENT] code: 'ENOTFOUND'. syscall: 'getaddrinfo' } error : smtp undefined I have changed the email-settings. 0 • Reply • Share › Stephen Braitsch Mark Coles • 4 months ago @Mark Coles Socket. Can somebody tell ma what print. Apologies if I'm reading it wrong.

How would you apply this to a real website? I ask this because of course on my computer at home I have mongo installed. nodejs installed. 0 • Reply • Share › Donald Trap • 5 months ago Thanks.7. 0 • Reply • Share › converted by Web2PDFConvert. Declan 0 • Reply • Share › WeLeven • 5 months ago Hi. how did u start the monogodb? Did it not install as a dependency? I tried to start it with mongod Reply • Share › Declan E. .3 install: `node-gyp rebuild` 190 error `cmd "/c" "node-gyp rebuild"` failed with 1 191 error Failed at the bcrypt@0. Another question I have. true ] 0 • Reply • Share › Stephen Braitsch Donald Trap • 5 months ago I had an error once attempting to download bcrypt due to one of the servers hosting it being offline. just want to know is there an easy way to prevent the same user from logging in from different machines (same IP but different ports.. bcrypt etc.1.7. I have registered an account an then tested it by logging in with it. or different IP altogether)? I tried to add state to each account of the user to tracked if they are logged in or out but it will fail if they close the browser without logging out first. • 5 months ago Stephen. I load cmd prompt. for example on my home computer.js" "install" "-d" 194 error cwd C:\Documents and Settings\Administrator\My Documents\GitHub\node-login 195 error node -v v0. 192 error System Windows_NT 5.and connect in my browser using localhost:8080.. now i'm experiencing an error within a few seconds of starting node app. when hosting this on the internet as you have done with your example for us to see. Error: failed to connect to [localhost:27017] 0 • Reply • Share › Donald Trap • 5 months ago Hi I'm currently having issues with the install..3 190 error bcrypt@0. I followed all the requirements/dependencies but still get errors when I run 'npm install -d' below is copied from my npm-debug 189 info postuninstall bcrypt@0.65 197 error code ELIFECYCLE 198 verbose exit [ 1. how do you go about this.1. However. 191 error not with npm itself.3 install script. 191 error This is most likely a problem with the bcrypt mongo.. that was it! 0 • Reply • Share › JOhn terry 0 • • 5 months ago Hey Donald.7. 191 error Tell the author that this fails on your system: 191 error node-gyp rebuild 191 error You can get their info via: 191 error npm owner ls bcrypt 191 error There is likely additional logging output above.then go to the login app's folder and run this.. I have the program running on localhost:8080 to test on my home computer. or try installing it again in a few hours. Where do I now go to actually see the databases created by the mongodb connection? So that I can get a clearer idea of what your program is storing and where...2600 193 error command "C:\\Program Files\\nodejs\\\\node.Never mind. I finally got it installed on Windows XP. Great program.14 196 error npm -v 1. and all the other features you need for other extensions such as npm..exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli. Thanks.8.

although understanding how I approached this problem may help you learn something. It is very frustrating because your code works nicely with Express 2. If you want to fork it and submit a pull request that would be fantastic. so It is really really helpful for me. I was expecting that It will redirect me to the login screen to login again but It did not:( 0 • Reply • Share › Stephen Braitsch 0 • Ali Hassan • 6 months ago Share › You have to manually logout for the "remember me" option to stop taking effect.js for us beginners .js 0 • Reply • Share › Stephen Braitsch Mihai • 6 months ago @mihai Use whatever works for your project. I'm new to Node and I'd like to ask you what are the modifications that need to be done to port your code to Express 3 ? I struggle for the last two day with it wo success :-( I've made lots of search in google and also asked in Stakeoverflow forum but with no response. If you are able to successfully migrate the project. 0 • Reply • Share › Florent Wozniak Stephen Braitsch • 3 months ago Hi Stephen. BUT:( One thing in which I am stuck is why the "Remember me" check is not working as desired:( I unchecked the "Remember Me" check and then quit my Mozilla Firefox but when I reopen your home screen " redirected me to the home page whereas. once I have unchecked the "remember me" checkbox and then I logout and return back to the login screen here still the "remember me" checkbox appears checked? 0 • Reply • Share › Ali Hassan • 6 months ago Is it should be the desired behavior? It should be in such way that when I have unchecked "remember me" checkbox and then I quit the browser. Stephen! Great intro to node. 0 • Reply • Share › braitsch Mod braitsch • 3 months ago converted by Web2PDFConvert. it's on my to do list but I haven't had the time. @mulyana I unfortunately have not had the time to port this to Express 3. then It should ask be to login again as its session has expired? Please correct me.Donald 0 • 5 months ago Would it be difficult to implement a captcha/recaptcha system to prevent spam? • Reply • Share › Andrei Soare 0 • • 5 months ago Thanks. Thank you for your reply (even a clue would be great). Flo 0 • Reply • Share › braitsch Mod Florent Wozniak • 3 months ago It shouldn't require much to migrate the app to . Reply • Mihai • 6 months ago Could i just ask why i should use my own (copying yours :P) login model instead of using something like passport? just want to know what advantages/disadvantages that might mean since im just starting with node. Express and firebug return to me no error.) Reply • Share › Ali Hassan • 6 months ago Also. go ahead and issue a pull request. 0 • Reply • Share › Ali Hassan • 6 months ago Hi STEPHEN. That is AWESOME!!!! I am making an website using the same technology that you have used.

Great tutorial and thanks for sharing.3.0. I want to aspire to aspire to this level of coding. 0 • Reply • Share › Stephen Braitsch Jake • 7 months ago Hi. Can you help me better understand where these variables are first instantiated. Cheers! Reply • Jake • 7 months ago Stephen .and 'd' inside the anonymous functions called from account-manager and router. I am going to try and fork your repo to see if i can get it to work with mysql. 1 • Reply • Share › Florent Wozniak braitsch • 3 months ago Many thinks Braitsch i really appreciate.'e'. and how they function within the program? Appreciative of any additional information you can Very clever way to structure code.0. require is returning a function and you are calling that function immediately and passing in app an exp.6 as of v1. Thanks again for writing this tutorial. If anything.. it's awesome to look through your code base.js. assigned. They are mapped to whatever values you pass to the function when you call it. I really appreciate . How about using a Session to remember a user ? e. 0 • Reply • Share › Stephen Braitsch 0 • Bryan Nichols • 7 months ago Share › Thanks Bryan for the feedback. HTH 0 • Reply • Share › Load more comments Comment feed Subscribe via email converted by Web2PDFConvert. Woundnt this be more secure? Or is that session ID some easy to fake? generate ? What do you think ? 0 • Reply • Share › Bryan Nichols • 7 months ago Stephen. In you example you store the username and the password in the cookie.I just updated the app to Express. I guess you now use 'extends' instead of layout in . I'm just beginning to learn javascript and node and am a bit unclear on the use variables 'o'.. I think I figured it out.: https://github.js v3. those are just the incoming arguments of the function. glad to hear you found this useful.jade file (got it) :) did you make other changes ? 0 • Reply • Share › daslicht • 6 months ago That you for this wonderful example. In that case only a session ID would be stored in the cookie.g.

converted by .

com .converted by Web2PDFConvert.