Ryan Chenkie: [0:00] One of our tasks here to make the app function correctly is we've got to take the user ID from the JSON Web Token that goes in on request to the API. We need to include that in certain database queries that we make.
[0:13] For example, the reason we can't switch over our user role right now is that we need the user ID that comes from the JSON Web Token to make that happen. In this endpoint that accepts PATCH request to API/userrole, we're looking for this property called sub.
[0:30] Right now, we're not able to get this property because this user object doesn't yet exist on the request. That's what we're going to make happen. Now, you may be asking, "Where does this sub property initially come from?" The answer is it comes from the payload of our JSON Web Token.
[0:46] This is a recently minted token that I've just pasted it into jwt.io. If we go to the decoded view in the payload, we've got this sub claim. Once again, sub is the subject. It stands for a user ID, something that can identify the party that is sending the token. This user ID is what was created in Mango as we created this user account.
[1:09] There are various other claims here on the token. One of the more important ones is the expiry, so when the token expires. But others that are, of course, important for our use as well. Our goal now is to be able to accept this sub claim from the token and use that in our database queries.
[1:26] For that, we can create a custom middleware that is going to take the token payload and attach it to the user object in the request that comes in. Let's do that just up here, right above our check JWT Middleware. Let's give ourselves a new middleware, we'll call it attachUser.
[1:43] That's going to be equal to a function that accepts a request that has a response and a next() function. Within the body here, we're going to start by taking the authorization header. That's where the JSON Web Token is going to exist on incoming requests. We can say cons token = requestheaders.authorization.
[2:04] Now, let's anticipate some of the issues that might arise here. If there is no token included in the request, we'll most likely just want to send back an error right away. We can check. We can say, "If there's no token, let's return a response with a status code of 401," which is for unauthorized. We can include a message here that says, "Authentication invalid."
[2:28] If we do get pass this block, let's give ourselves a constant of decodedToken. Our decodedToken is going to be a call to jwt.decode, so jwt-decode, this is a another library that we're actually already pulling in. It's up here jwt.decode. That's from a library called jwt-decode. You can install it just like this with npm.
[2:54] Back down at our middleware here, jwt-decode, which will accept our token and begin. Because our token is coming in on an authorization header with the Bearer scheme -- if you recall, when we send request to our API, our header here has Bearer and then the token -- we'll need to just slice away that top portion the Bearer portion.
[3:14] Token, we can call slice@index7. Then, let's check to make sure that we've actually got a decoded token. If anything went wrong, we can error out. If we get no decoded token, we can return a response with a status code of 401 again.
[3:30] We'll have some JSON in there with a message that says. "There was a problem authorizing the request." That is not the case, though, we can put in our Else block that our request.user -- we're modifying the request objects -- that's going to end up in our endpoints, request.user = decodedToken. To make sure control gets passed on to the next function, we are going to call next().
[3:56] We'll want this middleware pretty much everywhere throughout our application here, so all of the endpoints that sit beneath. Instead of applying it on individual endpoints, this is a good use case for calling app.use, and then we will use our attachUser middleware.
[4:11] Now, anything that comes beneath here is going to use this middleware. Request will pass through. We'll look for the authorization header. We will attach the decoded portion of the token to the user on the request object. That means that we should be able to get an indication of this user down here anywhere that we want.
[4:30] One way we can check this is we can just modify our dashboard data function here just to get a really quick sense of what's going on. Let's continue to return our response as we were. Before we do that, though, let's console.log(request.user). That should give us our token payload to look at.
[4:47] Let's save this, and I will open up the terminal again. If we come over to dashboard, let's see what we get. Over here, console.log(out) is our token payload.