Authentication using ReactJS, Redux-Saga, Passport.js and MongoDB Part 3

Allen Liu
3 min readJul 21, 2020

--

Photo by Erik Mclean on Unsplash

This is the Part 3 of my authentication app series. In Part 2 we have talked about how to setup Redux, Redux, Redux-saga, forms that users used to sign up or sign in and how to achieve login persistent.

In part 3, it’s time for us to add google and facebook OAuth to make this app cool.

There are many articles writing about how to setup React and Passport OAuth, but few mention Redux. It doesn't feel hard to integrate Redux and Passport OAuth at first glance, but some of the tricky stuff may cost you hours or even days.

Step 1: Setup Passport OAuth configuration

Despite the custom callback function, all the code can be found in passport documentation. Be aware that I used passport-google-oauth20 insdead of passport-google-oauth2 in the document. passport-google-oauth20 is more popular and update based on discussions on Stack Overflow.

You have to register your app on google or facebook cloud platform to get the client id and client secret. I suggest you to read these two articles to have a better understanding of the process. Both of them are written by Jon Preece.

For google OAuth:

https://developerhandbook.com/passport.js/how-to-add-passportjs-google-oauth-strategy/

For Facebook OAuth:

https://developerhandbook.com/passport-authentication-series/how-to-add-passportjs-facebook-strategy/

After following those steps in these two articles, you should be ok to set up every thing in the cloud platform and get your own client id and secret. If you are running the app locally like me, the callback URL should point to your server address.

On Facebook platform, you don’t need to specify the callback address if you use localhost.

The logic of the callback function in these middlewares is simple. Search the returned id (profile.id) in the database, if there is a match, return the user object. If not, create a new user, save it and return the user.

The returned googleId in our database

The profile property returned from the provider is different between providers. I suggest you to use debugger to check out the return properties and take what you want to store to the database such as email: profile._json.email

One thing you may ask, what is the accessToken and refreshToken? In our case, it is not nessesary to touch them. But can we remove them from the function since we don’t use these variables? The answer is no. If you remove them, the app will break. I don’t know why either, just keep it like this.

Step 2: Setup Routes for OAuth

You can find this on passport documentation. Our frontend Google and Facebook OAuth buttons are linked to these routes /google or /facebook. Passport will do the work for us to send request to OAuth provider. After the authentication process, the provider will redirect the user to the /callback route.

Step 3: Setup the OAuth button

Do not overthink here, just create a simple window.open or anchor tag with a the link pointed to the OAuth route (http://localhost:5000/oauth/google)in your server. Then the OAuth provider and passport will do the work for you and return a session id to your browser if login is successful. If you try to use axios or fetch api to do this work in Redux-saga, you will be rejected by the cors policy set by google server.

All right, here is everything I want to share with you. I hope this project can provide some help to you when you are building your own authentication system. The full project is here.

Feel free to contact me or leave a comment below if you have any question.

Email: allen6qi@gmail.com

--

--