Module 4 Summary

This lesson is a summary of the work we've done in Module 4.0.

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

Table of Contents

This lesson preview is part of the TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two with a single-time purchase.

Thumbnail for the \newline course TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two
  • [00:00 - 01:26] In this module, we spent our efforts in basically creating the functionality for users to authenticate and login as well as log out with their Google account in our application. We initially created a Google object within our Lib API folder that essentially consolidated the functionality that interacted with Google servers. We've constructed an OAuth object with the help of the Google APIs npm library and within the object that we export within this file, we have two functions, the OAuth function and a login function. The OAuth function essentially just generates an authentication URL from Google servers, which is the URL that we want the user to navigate to to sign in with their Google account. And the login function essentially uses the Google people API to get the relevant information for a user signing in with their Google account. And in our application, that was their email addresses, their names and their photos. We created three root level GraphQL fields. We created a OAuth URL query field that returns a string and is expected to return the authentication URL to the client. And we created two login and logged out mutation fields, where in both cases, a viewer object is returned. The log in mutation would be responsible in essentially logging a viewer into our application, while log out does the opposite to log them out.

    [01:27 - 01:40] We created the resolver functions for these fields within a single resolvers map called viewer resolvers. Viewer is essentially the term we use to constitute a user viewing our application.

    [01:41 - 03:18] And in this context, we've specified that the OAuth URL query field and login as well as log out are resolver functions that pertain to the domain of a viewer. The OAuth URL query field essentially simply returns the OAuth URL field from our Google object. The log in mutation does a few different things. It receives at first a code from the actual input that's fed into this mutation. It also then creates a random token. And this token would be essentially be used in the next modules to actually help conduct and prevent cross-site request forgery attacks . We then conduct a login via Google function and we pass in the necessary parameters, the code, token and database object. And this is where we then interact with Google's people API by running the login function within our lib Google object, specify and pass in the code that was given to us . And from there, attempt to retrieve the user information or the relevant user information, which at the very end is basically the user name, the user avatar and the user email. If this user that you're signing into with already exists in our database, we simply update the user document in the user's collection and update it with the new potential fields we can get from the Google API. If this viewer can't be found within our database, we simply insert a brand new document instead and lastly, the logout mutation resolver function essentially doesn't do much at this very moment and just returns an empty viewer object to the client with which the client can do on its own.

    [03:19 - 04:07] However, we're going to need the logout mutation in the upcoming modules when we deal with cookie sessions as well. Now let's move over to the client to see the work we've done over there to facilitate the changes we've made in our server. In the root index file of our client project, we've kept a viewer object as state, which is essentially the representation of the viewer who's either signed in or signed out of our application and will need this information everywhere in our application later on. We created the GraphQL documents for the three new root level GraphQL fields, such as the AuthQL query and the log in and log out GraphQL mutations. We also constructed a log in component that will be shown in the log in route of our application.

    [04:08 - 04:59] And it's in this log in component that we give the user the capability to sign in with their Google account. And the way we conduct this is we initially use the Apollo client objects to actually have the capability to query the AuthQL field when the user actually clicks the sign in with Google button. And when successfully authorized and the user logs in with the Google account, Google will return them back to the redirect URL we've specified in our Google developer console, which is the slash login route of our app. So they get taken back to this login component, which is why we have a user effect or constructed to essentially check and say does a code exist in the actual URL parameter. And if it does, it essentially means we've been redirected back to Google. And this is where we run the log in mutation and passing the code that we've retrieved.

    [05:00 - 05:59] And finally, when the log in mutation is successful, we simply redirect the successfully logged in viewer to their own user page. And lastly, another large piece of work we've done is we've also constructed an app header component, which is essentially the component element that will be shown in the header of our application, whenever the user is in any route within our app. And in this app header component, we give the user the capability to log out, or in other words, to run the log out mutation. And when the user simply clicks the log out sub menu item , we just conduct the log out mutation. Now, once again, this log out mutation at this moment doesn't do much. However, we're going to need it later on, and we deal with cookie sessions. And this is once again, to reiterate just a rough, larger summary of the work we've done. In all of these module conclusion videos, we're not going to dive deep into every single line of code. But instead, we're going to summarize the main pieces that we've done within the module.