Welcome to part 3 of the Twitaron series
- Getting started
- Views & Controllers
- User Accounts
- Under development…
In our previous article we leared how to add views, layouts, partials, controllers, and more.
In this installment of the Twitatron series, we will be diving into how to implement user accounts. By the end of this article you will have learned how to connect to MongoDB, used Mongoose for object modeling, implemented Passport for user authentication, allow users to login with their Twitter account, and have full support for user accounts.
Secrets
Before we go further into setting up support for logging in with Twitter, we need to add a way to easily develop locally and run in production. There are going to be settings that are different locally versus production and we don’t want these production values in our source code. There are many ways to handle this, but one way I like is to use a secrets module.
If you don’t already have a config
directory in the root of your application, create one now. Inside this directory, create a new filed named secrets.js
. Update this file to contain the following. We will be using many of these items in this and future tutorials.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
When your application runs in production, you can setup all the necessary environment variables so they are used within your application. When you run locally, it will use the values specified within this module.
The last thing we need to do is use this module within our application. Update the code in server.js
from our previous article to look like the following.
1 2 3 4 5 |
|
Connecting to MongoDB
If you don’t already have MondgoDB installed and running, you will want to go their official site and follow their installation instructions.
There are three things we need to do to connect to MongoDB.
- Install the Mongoose package
- Load the Mongoose package
- Connect to it using our connection string
Install the package manually using the following command:
1
|
|
Update the code in server.js
from our previous article to look like the following.
1 2 3 4 5 6 |
|
Connect to MongoDB
1 2 3 4 5 6 7 8 9 |
|
If all goes well, your application should start up just fine. You will notice we are already using our secrets module for the MongoDB connection string.
User Model
We now need a model to store our user. Inside the models
directory, create a file named user.js
and add the following code to it. If you don’t have a models
directory, go ahead and create one in the root of your application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
So what is going on here?
- We loaded the Mongoose package
- Created a Mongoose schema which maps to a MongoDB collection and defines the shape of the documents within that collection.
- We defined our schema to contain twitterId, username, email, name, created date, access token, and token secret.
- We exported the Mongoose user model for use within our application.
- We created two methods on our schema that we will use to encrypt and decrypt the access token and token secret.
Auth Controller
1 2 |
|
This will install the standard passport package along with passport-twitter. Passport-twitter will provide our application with Twitter authentication strategies. It will allow us to easily add Twitter login to our app.
In the controllers
directory, add a file named auth.js
with the following contents.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
What we are doing here is setting up passport to use the Twitter authentication strategy provided by the passport-twitter package. For our TwitterStrategy, we are defining a callback that will attempt to look up the user using the Twitter profile id and if found not found, create a new user. If all works well, it will return an existing user or create a new user.
The final piece of this is exporting the auth
and authCallback
functions which will be used within our application as route endpoints responsible for creating and logging users in via Twitter. Open up server.js
and set it to the following code.
Also, because Passport Twitter strategy requires sessions, be sure to install the express-session
package.
1
|
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
|
What we did here was to include the passport, express-session, and authController modules. After that we setup our Express application to use passport and passport session as middleware. Finally, we create two new endpoints responsible for logging users in via Twitter.
In order to test this, you will need to head to Twitter and register an application. You can do that here: https://apps.twitter.com/. Once you have an application, update the consumer key and secret inside secrets.js
.
You can now test things out by making a request to http://localhost:3000/auth/twitter
Clean up our views
Before we update our views to support logging in and out, we need to clean up our views and some of the code behind it first.
Open up homeController.js
and delete this line from the index action: res.locals.ip = req.ip;
.
Open up home.jade
and delete this line from the view: h2 You are visiting from #{ip}
.
Allow users to login and logout
To know whether or not a user is currently logged in, we need to add a little code to our Express application. One of the nice things Passport provides is that it automatically adds a user object to the Express request object when someone is logged in. We can take advantage of this by passing it to our views. Open up server.js
and update the code as follows right after we use passport.session.
1 2 3 4 5 |
|
What we are doing is adding the user object to the locals object in order to make it available in our views.
Next, we will want to update navigation.jade
to show login or logout depending on the user’s state.
1 2 3 4 5 6 7 |
|
The last thing we need to implement is a controller action for the route /auth/logout
. Open up authController.js
and add the following to the very end.
1 2 3 4 5 |
|
Now, just define your route within server.js
as follows.
1 2 3 4 5 |
|
Go ahead and try things out. You should be able to click Login with Twitter
, get redirected to Twitter, authorize access to your Twitter account, and have a User created or get logged in as an existing user.
Wrap up
We covered a lot of areas in this tutorial. First, we added a configuration module which allows easy configuration between development and production. Second, we learned about Mongoose and connected to MongoDB. Third, we created a Mongoose User model and created helper methods that allow us to encrypt and decrypt sensitive information such as access tokens and token secrets. Finally, we added the ability to log in with Twitter, have a user account created, and then log out.
If you found this article or others useful be sure to subscribe to my RSS feed or follow me on Twitter. Also, if there are certain topics you would like me to write on, feel free to leave comments and let me know.
Source code for this part can be found here on GitHub.