This course has been updated! We now recommend you take the Server-Side GraphQL in Node.js course.
Transcript from the "Authentication" Lesson
>> Scott Moss: So the next lesson I want to talk about is going to be our last exercise here. It's going to be authentication. This one is really cool. I really like authentication in GraphQL because it's like, you can literally do whatever you want. It's ridiculous, I love it. There are many ways to auth, so many ways.
>> Scott Moss: There is not a wrong way. So, basically, here are some of the ways that you can log or some of the ways that you can authenticate with GraphQL. One is you can lockdown the entire API by checking the authentication outside of GraphQL or when creating a context object.
[00:00:34] What does that mean? Well, basically outside of GraphQL. Okay, so let me show you an example of that. So right now, the only application we have on our server is an ApolloServer, but let's say that we had an express application that had some other routes on it. And then for slash GraphQL we mounted an ApolloServer there.
[00:00:56] That means we could just authenticate before the ApolloServer even executes, on some middleware before that, and that way we're authenticating before GraphQL even boots up. Before the request even gets to GraphQL, we authenticate. So that's authenticating outside of GraphQL. So you will lock down the entire GraphQL path for authentication.
[00:01:14] And that's fine. If every single GraphQL request that you're ever going to require needs authentication, you could totally do that. The other way you can do that if you don't have an express server and in our case it's just a server, Apollo, then you can do that here in the context object.
[00:01:29] So in this context object you can do asynchronous things, and you get the request object. This is the same request object you get in express. You have access to that. So there are going to be headers, authorization stuff, tokens, query strings, everything you need from a request to see if they're authenticated.
[00:01:44] You can do authentication in here. And if you don't like what you see, you can throw an error, and then no query or whatever execute. So you can do that here and you get the same benefit of kinda doing it outside of GraphQL before any query, before any resolver executes, you authenticate here, and that's kind of what we're gonna do today.
[00:02:03] So that's one way.
>> Scott Moss: You can also handle the auth and the resolvers. You've just got to make sure that you pass on to the context what you need so that the resolvers can handle that authentication. For instance, if you're going to handle auth and the resolvers and you know you need the header information, then inside of this context object you might want to pass on the request.headers authorization, or whatever you need to authenticate to the resolvers.
[00:02:30] And then inside of your resolvers, every resolver that needs authentication you would have to do it here. You would check here. If whatever, do this. So you can do that as well. We're gonna do a combination of both. We're gonna do something in the context. We're also gonna do something in the resolvers.
[00:02:47] So, that's another way.
>> Scott Moss: A third way which is really fire or really hot, it's a new hipster thing, is to use custom directives in your schema definition language. Well, we didn't talk about directives, but directives are basically an enhancement. It's a way to send metadata with your schema.
[00:03:10] So right now, we have these schemas that define shape and structure and validation, and stuff like that. But if send some extra information along with this field. Like for instance, I wanna add something else to let the server or to let GraphQL know there's something special about this name field, I wanna do something here, so you can use what's called a direction.
[00:03:28] So I can say you have to make this but you can use an auth directive assessment like auth and then you can say role has to be admin or something like that. And then you have to go implement this custom directive. Creating custom directives is really advance. We are not going to talk about creating custom directives.
[00:03:46] If anybody wants to know how to do them, I can show you the path to that after we get done with everything, but yeah you can do this. This allows you to lock down specific fields that need authentication. Like, yeah you can get all this and this and this, but you've got to be admin to get this field, or you've got to be a member to get this field, or you have to be whatever to get this field.
[00:04:06] So it locks fields down which is really cool. You could do the same thing with the previous approach where we were authenticating in resolvers. You can also lock down fields this way as well, right? You just make a resolver for that field, and then you check authentication inside of that field, and you can lock down that field as well.
[00:04:21] So it's the same way, it's just this is defined in the resolvers, the other way, it's defined on the schema, but it does the same thing. You can also use resolver middleware, and the reason I put it in some frameworks because not every framework supports resolver middleware. It's relatively new.
[00:04:36] I think it's really cool, but it's exactly what it sounds like. You can have a function that runs before resolver and you have a function that runs after the resolver, and that can be authentication. Only framework I know that supports that right now Is GraphQL Yoga, yeah, that's a framework.
[00:04:55] GraphQL Yoga, which is basically like the same thing as Apollo Server, it's just by another company called Prisma, they support Middleware. So, if you wanna use Middleware for authentication, you could use that as well. So those are some of the different ways, I can think of, doing authentication, and there might even be more than that.
[00:05:12] But, as far as I know, those are some of the ways you can do them. And they all have different tradeoffs, like I told you. Doing it outside of GraphQL means you lock down the whole API and everybody has to be authenticated. Which means you can never do sign up and sign-in through GraphQL because you have to be authenticated to use, GraphQL and if you're signing up, you're not authenticated.
[00:05:31] Handling the auth and the resolvers gives you superior control but it can be very tedious if you have a lot of resolvers to lock down. So, it's like I got to write this logic everywhere and it builds up. If your logic is asynchronous you have all these nested resolvers, you're checking the same logic every single time.
[00:05:47] So it can build up, it just adds more delay. Custom directives I would say is probably one of the cleanest ways, you just have to keep building custom directives so you just got to look into that which is not the simplest task. Using Resolver middleware, that's actually pretty easy but again it only works in certain frameworks, I don't think Apollo Server supports it.
[00:06:06] But GraphQL Yoga does, so check that out. So yeah, those are some of the ways that you can authenticate. Now what you do to choose authenticate is up to you. You wanna use JSON web tokens, that's fine. In this example, because we're a public facing API for this e-commerce app, we're gonna use API keys to authenticate.
[00:06:23] We won't have JSON web tokens just an API key, and we're gonna use that to authenticate, and then also to identify who the user is, and then also authorize if they're able to do something depending on their role. So we're gonna do all three, authorization, authentication and identification with API keys.
[00:06:41] And you're gonna implement that.