Current section: Protecting Routes 6 exercises

Authorization and User Authentication

Loading solution


00:00 To start, we're going to go to AuthServer. And in here, we're going to see what Copilot can do for us. So export a sync function called requireUser. And we're going to get the user ID. No, that's not quite right, Copilot. We're going to get the user ID from await requireUserID. Because we're requiring the user,

00:17 we're going to definitely require that they have an ID as well. And so all of the logic that we have behind requireUserID makes perfect sense in the context of requireUser. So here, now we're going to use Prisma to go find our user. If that user doesn't exist, then we've got a weird situation where they've

00:35 got the user ID in the cookie, but there's no user in the database that exists. We had the same sort of situation in the root. So we're going to log out the user, if that's the case, so that that won't be in their cookie anymore. And then we'll return the user. Yep, that looks pretty good to me. So then we can go to our note editor.

00:55 And in our action, so what happens when we hit Submit, let's go ahead and require the user. So here's our user is await requireUser from the request. And then we're going to add an invariant response here that will throw a response if what we pass is not the case.

01:14 So we'll say user.username must be equal to params.username. And if it's not, we'll say forbidden and give a status of 403. And that should prevent me from successfully making a change. Da-da-da-da, hooray. So we are solid there.

01:33 Now, it would also be good to not even be able to see this page at all. And so we're going to come over here to our edit page right here. And this loader is going to be responsible for that. So the route that we're looking at is this slash edit route. It's exporting the action, so that's why we're in the editor over there. And now for the loader piece of that,

01:53 we're actually going to do the same exact thing. So let's just grab that, stick that right here, and then grab require user and also request. And with that now, da-da-da-da, we're good. All right, let's do one more here. Let's go to new so I can create a new route.

02:12 I'm technically not allowed to do that now because we made this change in the note editor. And the new route uses that note editor action. But I do still want to not have this page show up at all. So we're going to export a async function loader.

02:31 And this is going to need the request from the data function args. And then let's see if Copilot can do this for us. No, it's not return. Come on, Copilot. OK, we've got that in my code board anyway. So we'll paste in the require user and invariant response. Let's grab the params.

02:50 And then here, JSON, we need to return something, or Remix isn't going to be super excited about it. So if I save that, then forbidden, ta-da. Yeah, good, good. All right, so let's see. We've got also on the note ID route, we have the ability to delete notes.

03:09 And so even though we don't actually currently show that the Delete button, our action still allows people to delete notes. And so we need to make sure that they can't do that. So we're going to just take that. That was in my code board. And paste that right in. It's the same process here. And now if I were to try to delete it,

03:29 then I wouldn't be able to. And that protects these particular routes. Make sure that we are only allowed to perform these actions if our username matches the username of the user that we're currently looking at, the owner of these notes.

03:47 And that is doing some authorization. We're going to actually expand on this a little further with role-based access control in our next exercise. But this gets us in a pretty good place where we say, you know, you absolutely have to be logged in. And for these things, you have to be

04:04 the user that created it, the owner of the note. And if that is the case, then you're allowed in. There you go. So just quick review. Require the user ID. If you don't have a user ID, we'll kick you over to login. Go get the user for that user ID. If that user doesn't exist, we'll log you out to get that user ID out of your cookie.

04:24 That's unlikely, but it does happen. And then otherwise, the most common case will return that user. There you go.