Check out a free preview of the full Server-Side GraphQL in Node.js course
The "Authentication" Lesson is part of the full, Server-Side GraphQL in Node.js course featured in this preview video. Here's what you'd learn in this lesson:
Scott demonstrates how to add authentication to an Apollo server, and explains that the level of authentication depends on what needs to be protected within the schema. Request level caching to avoid querying the database each time is also discussed.
Transcript from the "Authentication" Lesson
[00:00:00]
>> Scott Moss: This is basically the core of graphQL APIs. If you never get into stitching APIs together and having APIs gate graphQL APIs gateways and interested in data piper line stuff, this is it. Everything else beyond this is like I said, managing performance and security and how do you organize your app, that's it.
[00:00:20]
There's nothing more to it than I just described to you. So if you feel like you're missing something, you're not, this is it. I promise you, this is all it is. You can look at the documentation for Apollo, it's literally mostly that and them trying to upsell you on stuff.
[00:00:34]
There is so many ways to authenticate, and I'm gonna go over more detail on the advanced one, but basically, it depends on what you wanna protect. Do you wanna protect the entire API? Do you wanna protect one query? Do you wanna protect one field? You can do that in GraphQL.
[00:00:52]
It's up to you. You can say, everything is public except for this field. Only admins can see this field and then, you can do that. And there's a lot of ways just to do that one thing. You can do it in logic, in your resolver. You can create a custom directive that takes in a level of user role or something like that.
[00:01:10]
But obviously, the most simplest thing that you could do right now based off the stuff that we've been doing so far would be just to go and this is just to log down the host server. Would be to go into Serverjs and inside this context object, you would lock it down here.
[00:01:24]
So basically this context object gets access to the request object from Express. ApolloServer is based off Express. If you never used Express, it's a server that's based off something called Connect which is something a long time ago. But basically you get the incoming request object here. If you wanna get the headers on here, you can say, reg.headers.authorization.
[00:01:44]
You get the authorization header here, maybe you have jwto here or something like that. Whatever your auth schema is or cookie, whatever that is. And then you can async stuff in here so then you can come in here and be like cool, decoder jwt, check the user of the database.
[00:02:00]
If none of that's good, then I'm just gonna throw an error, throw error. And I'll just try this right now, not auth. So let's just do that, you'll see what I'm talking about. So we'll just throw an error here,
>> Scott Moss: Where is this thing?
>> Scott Moss: Starts up, looks innocent, looks good.
[00:02:25]
And then, boom, you try to create something, it says you're not auth, you can't do it. So, that's probably the easiest way to lock down your entire server. But again, if you have sign up and sign in implemented in your GraphQL server then you can't lock down the whole server because nobody can sign up or sign in.
[00:02:40]
So maybe you just wanna lock down these parts or just these parts. From there, you're gonna have to get to like, if it is a middleware, or directives, or hard coding your logic and a resolver, that's basically it. Any other questions?
>> Speaker 2: Can I ask a [INAUDIBLE]?
>> Scott Moss: Yes, yeah.
[00:02:57]
>> Speaker 2: Okay, [LAUGH] so if you have an application that has a bunch of services, do people typically call those services from within GraphQL? Or do they start to deprecate those services and do more in GraphQL?
>> Scott Moss: That's the beauty about GraphQL. It literally works with any service you have.
[00:03:19]
You never have to ger rid of it, you never have to change it. You just throw GraphQL in front of it. So, if you have a whole bunch of services and you want to unify them, the best approach is to create what's called. Well, are those services GraphQL services or are they not?
[00:03:32]
>> Speaker 2: They're not GraphQL services.
>> Scott Moss: That's easy. If you're not doing GraphQL services, then all you would do there is that they solved this problem already. You don't even need this, it's just makes it easy, data sources. But basically there's a thing called data sources in Apollo, so we have the models inside of our resolvers that we use to query our database.
[00:03:53]
Data sources are used to query services. So you just make a data service for each single service that you wanna query. And then you just inject those into context. Just like we did the database, just like we had the models, just like we did the user and inside your resolvers, you can just call these data sources which will call some service that you have somewhere else, and that's basically it.
[00:04:12]
The resolvers don't care where the data come from, as long as they meet the shape that's in the schema. So I didn't talk about databases too much. But as you would imagine, the reason I built this database the way that I did is because I wanted to abstract away the database but I mean, this is exactly what a database thing will look like, anyway.
[00:04:31]
So you can imagine if you would have went and replaced this in the database, it would work. And like I said, resolvers can return promises, they can also so async await. So you can just return a promise here and enter the resolver for you. So, that's why I'm also returning stuff here.
[00:04:43]
So, you can do whatever you want and it still works. It doesn't matter what database you want. You can have multiple databases, if you want. Just pass them in, in the context object and switch between them. Doesn't matter, you just gotta return that shape. And then you have to figure out caching and things like that.
[00:04:58]
Request-level caching is a big thing in GraphQL. How do you cache per request, right? So if I'm asking for the same thing over and over and over again, each one of these is a database. I already got this owner up here, why do I have to get it here, and why do I have to get it here again?
[00:05:13]
I should be able to cache that specifically just for this request. So there's like request level caching and memory that they use. There's persistent caching in something like Redis or MIM SQL or MIM cache or whatever like that. So there's different types of caching, but request level caching is probably the one that people get into the most.
[00:05:32]
And you could use something, and I think that's what this data source does. This data source handles a lot of that request level caching and then something like data loader is something that also handles request level caching. And you can use those in combination, data loader and data sources.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops