1. 程式人生 > >React Authentication with Twitter, Google, Facebook and Github

React Authentication with Twitter, Google, Facebook and Github

Server

Since the server is where we are going to store the API keys, we will need to get those keys from the providers that we are working with. Here are the instructions to get your keys for Twitter, Google, Facebook and Github.

Make sure that callback URL you provide when registering an app is in the form:

https://localhost:8080/__provider___/callback

After signing up for each provider we need to plug those keys into a .env file on the server. If you need a little help with that, please read this.

We are now ready to move on to writing the server:

Server.js is pretty lightweight as a lot of the functionality for the application will be shelled off to other files.

The key bits to note are that the application is started in HTTPS mode on line 22 (more on that below) and that the sockets are set directly on the app on line 45. By attaching the socket to the app, the socket can be accessed in the routes at a future point in time when we need to communicate with the client.

On to the PassportJS setup:

We are pulling in the strategies for the different providers that we are working with and adding those to the Passport singleton so they can be used throughout the application. If you have worked with Passport before this will feel familiar.

If you haven’t worked with Passport before, this is a great tutorial.

What is a little unusual above is that the callback on line 21 is the same for all the OAuth providers. Normally that callback is where you would save the user to a database and would need to be configured for every provider individually.

Because saving user data is not a focus of this tutorial, the callback is intentionally generic in this example.

With Passport all set up and ready to go, lets take a look at the router:

We have some setup to incorporate the PassportJS middleware and then have written a small piece of middleware on line 17 to attach the socket id of the connected client that comes in on req.query to req.session.

addSocketIdToSession — Attaches the socket id to the session and allows the server to send back the correct user info to the correct socket when the authentication process is complete with an OAuth provider.

I like to break up routes and callbacks into different files on the server to keep code modularized. But the previous file and the next file could be combined.

Time to look at the next (and final!) file:

Because we used app.set(‘io’, io) in server.js we now have access to the sockets from anywhere in the application that has a request in scope. This is super handy as we can now accept a callback from an OAuth provider and then relay the user’s info to the client via sockets.

Although this code is quite repetitive, at some point we have to build a user Object to send to the client and every OAuth provider sends their data in a different shape. Given that, there does not appear to be a way to avoid what feels like unnecessary boilerplate.

<side note> I would normally move configuration functionality like this into the callbacks of the passportInit function as mentioned above and move the user into a database at that point in time. But this seemed more straightforward given we are not saving any user data in this tutorial. </side note>

And thats it!

The server is not as easily extensible as the client, but we have established a solid pattern where adding an additional OAuth provider requires installing/configuring the PassportJS package for that provider, setting up a couple routes and writing a controller method.

Not too bad.