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:
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 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