Any application that stores user data requires some form of authentication. In this series, I’ll be showing how to handle authentication in GraphQL. We’ll begin by looking at an overview of authentication and how it is handled in GraphQL.
Then we’ll move on to practically adding authentication to a GraphQL server in two ways: manually adding authentication with JWT and using Auth0.
In this first part of the series, we’ll be looking at an overview of authentication, how it is done in GraphQL and how is it different from REST.
To get started, let’s look at what authentication is. Authentication is the process of determining claimed user identity by checking user-provided credentials. For instance, to log in to an application, a user must provide some kind of credential with which to identify themselves. These credentials can be a username/password pair or a kind of token. If the credentials matches what’s in the application database, the user is logged in.
Authentication is the process of recognizing a user’s identity. It is different from authorization. Authentication and authorization are commonly used together as they work hand-in-hand but they are completely different.
Authorization occurs after a successful authentication, it check the access levels or privileges of the user which will determine what the user can see or do with the application.
We’ll be focusing our attention on authentication in GraphQL in this tutorial.
If you have ever done authentication in REST in the past, you will know that there are different ways it can be done, include using Basic Auth, Hawk, Bearer Token, OAuth etc. Let’s take a look at how authentication can be done in a typical REST API built with Express. We’ll use JWT for the purpose of this tutorial:
As we can see, in a REST API, we can easily restrict an endpoint to only authenticated users by adding an auth middleware to it. This way, all other endpoints can be accessed freely.
In the code above, the /comments endpoint can be accessed without authentication, but the /comments/create endpoint requires users to be authenticated.
Then users can be authenticated through a /login endpoint like below:
Since GraphQL has only one endpoint, which all requests are made through, we simply apply the auth middleware to that endpoint. Just as with REST, the jwt will check if an Authorization header with a valid token is available on every request made to the endpoint.
If present, it will decode it then add a user object to the request. Otherwise, user will be null. So, we can get the details of the authenticated user with req.user. To make useravailable in GraphQL, we add it to the context object which is passed as option to GraphQL. Thereafter, we can use the user object however we like.
To authenticate users, we can add a login resolver function like below:
The only difference here is in the authentication middleware which makes use of Auth0 specific details to check and verify the JWT obtained from the incoming requests.
From our GraphQL server implementations above, you can see that applying the auth middleware to the GraphQL endpoint automatically makes all our queries, mutations etc. secured.
In many cases, this might not be what we want. If we are using an auth middleware package like express-jwt (which is highly recommended when using JWT) as in the example above, we can prevent that by setting credentialsRequired to false.