Module 5 Summary
This lesson is a summary of the work we've done in Module 5.0.
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo 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.
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.
Get unlimited access to TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
[00:00 - 00:26] In Module 5, we build on top of the previous module and look to help conduct persistent login sessions within our application with the help of cookies. In the root source index file of our server project, we use the cookie parser library as our server middleware, and in our polo server constructor, within context, we've now passed in the request and response objects in addition to the database objects.
[00:27 - 00:53] In the viewer resolvers mat file, the very beginning we construct an options object for the information of a cookie that will want to set with the help of the cookie parser library. And within the login via Google function, once the user has successfully logged in, we set a new cookie labeled viewer with which we give the user ID value.
[00:54 - 01:23] And we pass in the options that we've constructed above. We only introduce one other option that essentially says the maximum age of this cookie is a year since we don't expect this cookie to expire at a short period of time. We've constructed another function called login via cookie, and this function is called within our login mutation resolver under the context that when login is actually fired and a code doesn't exist, it probably means the client is attempting to log in via cookie.
[01:24 - 01:41] And in this login via cookie function, we essentially try to find a user document in our user's collection where the user ID is equal to the viewer cookie value. And we have this cookie value as the user ID we would have set when the user has logged in via Google.
[01:42 - 01:59] We've also updated the logouts resolver function, where in this particular function we make sure to remove or clear the value of the viewer cookie if it exists. One other additional change we made in the server is within the libutils file we've introduced a function called authorize.
[02:00 - 02:23] And in this authorize function we help to prevent or aim to prevent any cross- site request forgery attacks later on when we need to conduct sensitive changes or work in our actual application. And we attempt to do this by simply attempting to retrieve the token or the cross-site request forgery token from the client and verifying if this particular token matches that within a user document in our collection.
[02:24 - 02:49] And if it does, it basically means that the person making the request is the actual viewer or user that's intended to make the request. We don't utilize or use this authorized function just yet, but later on within the course when we conduct some sensitive work such as maybe changing a user information or conducting a payment, we'll always want to ensure that the person making the request is the actual user, so we'll run the authorized function beforehand.
[02:50 - 03:08] Now, when we move over to the client app, the main change that we've made is that in the root level index file or the root level app component whenever this app component renders, we would actually attempt to conduct and run the login mutation. And this is how we attempt to see if the user can log in via a cookie.
[03:09 - 03:32] And when the user is able to log in successfully with this cookie, we simply set the token value returned from the reviewer object from our mutation as the token within our session storage. And it's this token value within our session storage that we pass in as part of the XCSRF token header value for all our requests through the Apollo client constructor.
[03:33 - 03:53] And lastly, the only other UI change we made is sort of to facilitate the loading and error states of this particular login mutation. So if this login mutation is being fired and the user is attempted to log in via a cookie, we show a skeleton component of the app header and simply a spin component that tells the user that we're launching tiny house.
[03:54 - 04:11] But in other words, we're simply trying to log the user and via cookie. And if anything ever goes wrong, we simply just show the application, but we place an error banner up top to just tell the user that we haven't been able to verify that if you were logged in. Good.