OAuth using MEVN Stack

Ramakrishna Pattnaik
Zairza
Published in
7 min readAug 25, 2019
The MEVN Stack

Hello Friends! Hope you are all doing good :). If you use nodejs and you need to implement Oauth or just looking forward to learning something new in the server side programming, this article is for you xD.

Here I will be walking through the basic implementation of GitHub Oauth(that amazing feature through which we can sign up through GitHub) using REST architecture, with a nodejs server, vue.js client and MongoDB database. The mighty MEVN stack! Familiarity with this tech stack is a pre-requisite to best understand this article.

Stuffs we will use : -

NodeJS : Node.js is a JavaScript run-time environment which allows us to write our server-side code in JavaScript as well. It represents a “JavaScript everywhere” paradigm, unifying web application development around a single programming language.
ExpressJS : It is a Node.js framework designed for building web applications and APIs, It has been called the defacto standard server framework for Node.js.
MongoDB : A database program, MongoDB uses JSON-like documents with schema.
Vue.js : A relatively young JavaScript framework for building user interfaces and single-page applications.
Passport.js : Passport is authentication middleware for Node.js. Extremely flexible and modular, which provides an abstraction layer over logging in with various providers such as Facebook, Google, Github, Twitter and more.
Axios : Axios is a Promise-based HTTP client for JavaScript which can be used in your front-end application and in your Node.js backend. It makes it easier to send asynchronous HTTP request to REST endpoints and perform CRUD operations.

What is OAuth?

Authentication is the most common way to handle security for all applications. It is the app asking “who you are” through which using which it determines “what can you see” and “what can you do”. OAuth stands for Open Authentication which is a protocol which allows authentication based upon the credentials provided by third party services such as Google or Github. Compared to traditional approach where an user needs to register before authenticating, OAuth saves time by letting us use an existing account for authenticating purposes.
The various perks of using OAuth are :
1. No need to remember a lot of passwords. (I frequently click on forgot password, an humble request to please use OAuth here 🙏).
2. No need to fill the long registration form or OTP verification.
3. OAuth providers always give an option to revoke permission of any app granted OAuth permission.

PassportJS

There are various JavaScript user authentication libraries like passportjs, auth0, permit and grant. We’ll be using passportjs here. It is the most commonly used JavaScript library for user authentication. It is highly flexible and modular and can be integrated to any express-based web application. It supports various kinds of authentications including username and password, google, Facebook, GitHub, etc.

It implements various strategies or authentication mechanisms packaged as individual modules. Applications can choose which strategies to employ, without creating unnecessary dependencies. Passport-GitHub2 is the strategy for authenticating with GitHub using the OAuth 3.0 API.

Why this tutorial? (Problems with REST API)

They say necessity is the mother of invention 😎. I felt the need to write an article on this topic after struggling through implementing “GitHub login” in an application using REST architecture. I was able to finally implement it after going through a lot of videos, articles and documentations. I hope this article saves you the time and effort that I had to go through.
It is quite easy to implement it if you use server side rendering. There are many articles and tutorials that can guide us through implementing passport strategies using ejs or pug. I went through this tutorial. It helped me understand various aspects of OAuth and Passport. I would suggest to check out this awesome tutorial sometime. What it doesn’t cover is, implementing OAuth in REST architecture.

Now the best part, let the coding begin

Your machine should have NPM , Node and MongoDB. You can follow these links to have them installed :-

The server

We’ll be using express-generator which lays down a quick boilerplate for our express server. To install it :

sudo npm install -g express-generator

Now let’s use it!

express server --ejs
cd server
npm install

Thus we have our server with ejs as the templating engine with some of the dependencies installed.

Create a new OAuth app in GitHub :

  1. Login to your github account
    Go to Settings > Developer Settings > OAuth apps
  2. Click on New OAuth App.
  3. Provide application name, home page url, callback url and an optional application description.
  4. After creating the application, you’ll be redirected to the application page with important credentials such as client secret and client ID, which we’ll be using in our server.
The GitHub App Settings Page

Let’s code the server!

npm install --save passport passport-github2 mongoose cookie-session cors
  1. Create the schema for a user model. I am skipping the part of setting up mongoose with Node.

2. Passport setup, using the GitHub strategy.

3. The authentication routes. (to be hit as /auth/)

4. Add the following lines to your app.js

5. Let us start the server now

node ./bin/www

6 . Navigate to /auth/github.

Modal asking for access

7. Navigate to /auth/check.

The data stored in the session.

Hurrah! our server is working now.

The client

As mentioned earlier, the client will be a vue.js app. We will be using vue-cli to setup our app. You can install vue-cli by :

sudo npm install -g @vue/cli
  1. We will use the vue-cli to generate the boilerplate for our client with default babel and eslint configuration.
vue create client
Vue-cli

2. Install axios, the only dependency we’ll need in the front-end 😃.

npm install --save axios

3. Let’s change the contents of HelloWorld.vue

Before signing in

Let’s change the redirect url of passport to localhost:8080 instead of localhost: 3000 in callback method of the callback url in auth-routes.js.

res.redirect(“http://localhost:8080/");

4. After signing in :

The response we get in client.
The response we get on making request via browser.

Wait, how is this possible!! We are getting different responses on hitting the API from client and browser. Well, this is where the credentials option of CORS comes into play! The cookie created by cookie-session needs to be sent from client to the server. To make it happen, we have to enable credentials in both client and server side.

The Access-Control-Allow-Credentials response header tells browsers whether to expose the response to front-end JavaScript code when the request's credentials mode is "include". Credentials can be cookies, authorization headers or TLS client certificates. For a CORS request with credentials, in order for browsers to expose the response to front-end JavaScript code, both the server (using the Access-Control-Allow-Credentials header) and the client (by setting the credentials mode for the XHR, Fetch, or Ajax request) must indicate that they’re opting in to including credentials.

Keeping these in mind, we will have to tweak the code a little.

Changes in client

axios
.get(‘http://localhost:3000/auth/check', {
headers: { “Content-Type”: “application/json” },
withCredentials: true
})
.then(response => {
console.log(response.data);
});

Changes in server

var corsOption = {
origin: true,
methods: ‘GET,HEAD,PUT,PATCH,POST,DELETE’,
credentials: true
};
app.use(cors(corsOption));

Now let’s login again, we can see the user data in the console!!

It is working now 😎

Congratulations!, you just setup a fully functional example of GitHub sign-in. The vue.js client can communicate with RESTful API and authenticate any GitHub user.

You can find the entire source code in GitHub:

Feedbacks are always welcome, will be glad to know a better approach to this problem. I hope you found this article informative and useful. If you have any questions or suggestions, feel free to contact me on twitter @rkpattnaik_780.

Thank you for being patient throughout this long article. 😸

Do check these amazing links to know more :-

--

--