At this point our NavBar component
is calling the "/api/user" route,
and can display the user name in the header,
along with the "Sign Out" button.
The only thing that's still missing is that
if we click "Sign Out" nothing happens.
So let's go and add that functionality.
On this "button" we want to add an event handler,
that is "onClick",
and here we can pass a function
called "handleSignOut",
that we need to create.
Let's put it after all the hooks,
and before returning the JSX elements.
Now, let's think for a moment
what we need to do in this function.
We want to delete the cookie.
But remember that, for security reasons,
we are setting this cookie as "httpOnly".
So it's not possible to modify the cookie
from the client side.
We can only do that from server side code.
This means we'll need to create
another API route for the "logout",
in order to remove the cookie.
This will be another handler function,
let's call it "handleLogout",
and we can start with the usual 200 response
with an empty JSON object.
I should have written a user snippet
for this boilerplate code.
But anyway, how do we delete a cookie now?
That's actually pretty similar to
how we set the cookie in the first place.
So let's start by importing the "cookie" module
into our new API route.
And then we can go and copy
the code that sets the cookie as well.
Here we want to chain the "setCookie" call
on the response object.
Now, to delete a cookie
we can set its value to an empty string,
and we want to keep the same "path",
but the most important thing is that
we need to set the "expires" option
to be a Date in the past.
So we're basically telling the browser:
this cookie is expired, so you should discard it.
Now, I'm passing "new Date(0)" here
because this will create a date
at 0 milliseconds past the epoch,
so this results in January 1st 1970,
which is the epoch for JavaScript dates.
The important thing is that it's a date in the past,
which will tell the browser
that the cookie is already expired.
Ok. Now that we have our new API route,
we can call it from the NavBar component.
When the user clicks "Sign Out"
we can call "fetchJson"
and request the "/api/logout" route.
Let's make this function "async"
so we can "await" the "fetchJson" response as usual.
We're not actually going to use the result,
that's just an empty object anyway.
But we still want to wait for the response,
because after that
we want to update the "user" state variable,
so that this component will be re-rendered
and show that we're no longer signed in.
In practice we want to call "setUser"
and pass "undefined" as the new value.
This way we effectively re-set the state
to its initial value.
If the "user" variable is a falsy value
that means we're not authenticated.
Ok. It's time to try if this works.
I want to keep an eye on the network requests
so let me open the right tab
in the Chrome Developer Tools.
Ok. Now, if we click "Sign Out",
you can see that the NavBar immediately updated
and is now showing the "Sign In" link,
so we have been signed out.
And if we look at the Dev Tools
it made a "logout" request,
which is of course a call to our API route.
Here we can see the "Set-Cookie" header
returned in the response.
It does says "Expires: 01 Jan 1970".
As a result the cookie should have been removed.
This tab just shows that the response cookie
had an empty value,
but if we look at the Application tab,
here you can see that there is no cookie any more.
So it has been discarded by the browser.
All right, this concludes this section
about authentication.
We've seen how to log out
by removing the jwt cookie from an API handler,
that is setting its expiry in the past.
Even though our authentication functionality
is now working fine,
in the next section we'll see
how we can cache API responses
and generally improve all the code
that makes HTTP requests from the client side
by using a library called React Query.