Instructor: We've made some major progress
on our application here.
We've got the ability to sign in, sign out,
protect routes, blah, blah, blah.
You know, we've gone over it several times,
but there's still one very core aspect of our application
that we haven't addressed at all.
I'm gonna pull up the code for our server
that we had written previously, specifically the router.
So if you recall, inside of our router
we had this root route right here,
and the only response to that root route was a message.
And we were sending back a string right here.
So message, super secret code is ABC123.
That kinda twist about this route is that we protected it
with this requireAuth middleware right here.
So this requireAuth said,
"Hey, if someone is trying to access this route
"we need to verify that they have a correct
"and valid JWT token attached to the request."
So this was really the whole impetus
behind talking about authentication.
Not only do we want users to be able to sign in and sign up,
but we also wanted to make sure
that they could get access to very particular routes
inside the application that were secured by the JWT token.
So this is the last part of the application
that we need to work on.
We need to make sure that after a user signs in,
they can make an authenticated request.
So this is where the JWT on the client side
is gonna come into play.
Up until this point, we've really been pretty
kinda ignored the JWT token altogether, I would nearly say.
Sure, we kinda picked it up and we saved it,
and we kind of used it to decide whether or not the user
is currently logged in.
But we haven't really used the token itself
to make any type of request or anything.
And so now we're gonna go into the realm
of the JWT token itself.
So again, the token's purpose is to be able to make
authenticated requests to our API server.
And so to get a really good example of this going,
we're going to eventually need to put together
some type of request to reach out to that root route
on our server.
The... Oops, just lost it.
There it is. The root route right here.
So this is our goal.
We want to make an Ajax request to this root route
and we want to make sure that we send along
our JWT token as well.
So here's gonna be the kinda the order of operations here.
Here's how we're gonna tackle it.
First, we're gonna make an action creator to make a request.
So we're just gonna make an action creator,
we're just gonna make the request.
We're gonna hook this action creator up
to our feature component.
And remember, the feature component right now
is pretty empty, pretty straightforward.
Once we get it hooked up,
we're not gonna send along the JWT token.
Instead, we're just gonna take a look at the request
and see kinda what happens
when we don't send the token along?
What type of irresponse or error message
do we get from our server?
And then we'll go back and revise the request
to include the token as well.
So let's give is a shot.
Like I said, the first thing we're gonna be doing
is going to make an action creator for making the request.
I'm going to export a function called fetchMessage.
We're going to use Redux Thunk again.
So I'm going to return a function that's called dispatch.
Keep in mind here that we could have just as easily
used redux-promise for this part.
We're just making a very simple,
very straightforward Ajax request
just to get some JSON.
So we could definitely use redux-promise here
just to stay consistent with the rest of our app.
We're gonna continue making use of Redux Thunk.
The two of them, I wouldn't say necessarily
are mutually exclusive, but definitely if you have one,
you tend to not really need to make use of the other.
So inside of this Redux Thunk function,
I'm gonna make a GET request to the root URL.
And if you recall, the root URL
was defined at the top of our page
as just local host 3090.
So this really is like a request
to the root route on our API.
I would expect that this request right here
should show me the message,
super secret code is ABC123.
Let's actually test that out.
I'm gonna take off the semicolon.
Let's put on a .then case.
And we'll say that when we get the response
I want to console log the entire response.
So let's just see what we get out of this thing.
We've now got an action creator,
but it needs to be actually called somewhere.
As I mentioned, we're gonna be using
the Feature component for that.
So let's pull open Feature.
Now inside of Feature, if we want to call an action creator,
we're going to need to import our actions,
and react-redux as well, the Connect helper.
So let's do both of those.
I'll import connect from react-redux,
and I'll also import star as actions from up actions.
There we go.
Then we'll use our connect helper.
We're not gonna be making use of map state
to props just yet.
So I'll throw a null in there,
actions as our second argument.
And now to call the actual action creator,
let's hook up our component, willMount.
So as soon as this component is about
to be rendered to the screen,
we will call our action creator
this.props.fetchMessage.
Cool. So this should probably be enough
to make our Ajax request.
And just kinda see what happens
when we don't include our JWT token hearing.
Remember, the token is not included by default.
It is something that we very specifically
have to include with our request.
So right now we're just saying,
you know what, just make a request.
Let's just see what happens.
So I'm gonna flip over to Chrome,
and we immediately refresh the page onto Feature.
It looks like we're making a request here,
which is the action creator.
But it's returning a 401,
and a 401 basically means unauthorized.
You cannot get access to this content.
So we're definitely in an error state right here,
which is exactly what we want and what we expect.
We definitely want to see an error message here
when we do not include our token.
Let's go back and revise our code now,
and revise this request to include the token as well.
Remember to make an authenticator request for the token,
we're going to include it in the headers of our request.
So to add a header with axios,
I'm gonna take the root URL right here.
We're gonna put an object after it.
So I have root_URL, object.
We're going to say, here are the headers.
I wanna include authorization,
and we'll pull out our token.
Here we go.
So the second argument for the axios.get
is kind of a options object of sorts.
And so we can pass in some optional headers,
one of which will be specifically authorization,
which is gonna be our JWT token.
So now let's give this a shot in the browser again.
I'm gonna refresh.
And now it looks like we successfully did a 200 request.
Here's the message, super secret code is ABC123.
And I've got a data property.
Here's the console log response right here.
So, awesome. So this is how once our user is authenticated
this is exactly how we're going to end up
making an authenticated request to our backend
using our token right here.
This approach right here is a 100% reproducible.
You can throw in your headers all the time
as much as you want, just make the request.
Just remember to include your token
with the request as well.
So this looks pretty good.
It would be nice if we kind of showed the message
that we got back, you know, that message
in our actual feature component,
just to bring the entire project through to completion.
So let's go through that entire process.
I'm going to add another case
to the existing off reducer we have.
The off reducer isn't really appropriate
for putting this message in here,
but you know, what the heck?
Let's just, rather than go through the process
of making a totally new reducer,
we'll just reuse the existing one for right now.
Let's take care of wiring up that message
inside the next section.