This course has been updated! We now recommend you take the API Design in Node.js, v3 course.
Transcript from the "Authentication" Lesson
>> Scott: Which is protecting resolvers and testing. So we're gonna have an exercise on testing, we're gonna talk about protecting resolvers. There's really not an exercise because our app is not a production app. We don't really have any roles and stuff like that. But we can talk about it.
[00:00:20] So protecting resolvers, so you saw that I added back the JWT middleware for,
>> Scott: The path of /GraphQL right at the beginning of the app, like we did for the API router. I added that here.
>> Scott: Where are you? There we go, so I mounted it here.
>> Scott: Can anybody think of some downsides of this, if I block my whole GraphQL router?
>> Speaker 2: Testing is gonna be a lot harder.
>> Scott: Testing's harder, okay, what else?
>> Scott: What if my GraphQL router is responsible for signing up users? Now you can't sign up users because you've just blocked off your whole GraphQL API, because you need to be signed in to use it, right?
[00:01:09] So it's like the same problem as this. That's why there's a signin outside of this, because you need to sign in separately. So there's a lot of downsides. With REST, the way we would have solved this before is we would just make another router, not using that middleware, right?
[00:01:24] We'd make another router. In GraphQL, we don't really wanna do that. We don't want many GraphQL routers. We just want one GraphQL router. If we make another router, we can make another schema, more resolvers. It's just a lot of duplication. So what we do instead is, if you don't want your whole GraphQL router using the exact same global middleware, then what you would do is, you would take the logic out of that middleware.
[00:01:47] So whatever this thing is doing, you would use it on a per resolver basis. That might sound tedious and redundant, but if we think about it, it's actually really flexible.
>> Scott: So you can use express global middleware, just like we are with REST, right? You can lock your whole GraphQL API, but you can get some really undesired behavior, like I just described.
[00:02:07] Or you can do it on a per resolver basis, and this is really great for things like role based systems. Imagine if you had a role based system. And you wanted to lock down literally every single field that somebody can access, you can do that. Because we can write a resolver for every field, as we just found out.
[00:02:23] And because you have that user and the roles inside the context, you can say, does this user have the right role to access the payment field on the org type? You could do that. And you can limit that one field on that entire object per role. Whereas you can't really do that easily now.
[00:02:42] You have to do a lot of sanitizing to that mainly yourself. Or right now, GraphQL is pretty free. As soon as you get inside your resolver, does this user have the rights for this, for this field right here? Nope, nah, get out of here, done. Throw an error or just send back null, depending on what you wanna do.
[00:02:58] It can be tedious cuz you're doing the same thing over and over and over again to try to help a function. Put it somewhere, test it, use it wherever you want. It's not as bad as it sounds, if it's just one thing, it's very useful. I can tell you right now, I'm doing this for type, it's pretty much our architecture.
[00:03:14] We have a similar role based system that you will find AWS where you're like policies and roles. And this allowed us to literally lock down, we can lock down you clicking a button if we want to. It's ridiculous. Because of this, it's really good. You have way more control obviously.
[00:03:31] Like I said, per field level control. You can lock things down per object, per whatever, you can lock it down. But you also have to handle, you have to decide on how you wanna handle non authenticated requests. So you have two options, you can throw an error, which will just break the whole query.
[00:03:48] For instance, let's say somebody tried to access, they have access to this object, but they don't have access to this field on this object. So if they tried to access it, you could throw an error and therefore they get nothing back. Or you can just make sure in your GraphQL schema that you don't put the exclamation on everything, and you just return null for it.
[00:04:06] So they just don't get that value back. And their query doesn't break, they still get back the values they can see, they just don't get back that one field. That field will always be null for them, right? So it depends on how you wanna do it. You wanna throw an error, they shouldn't be accessing it.
[00:04:17] Or you just wanna only give them the stuff that they should have and take away the non-nulls for the stuff. So it's totally up to however you wanna do it, depending on your situation. But you can do that, whereas what we did yesterday, you're really writing your own system to do that.
[00:04:31] And it's gonna be pretty complicated, I can promise you.