Skip to content

Authentication in GraphQL Serverless

In the previous part of this tutorial series, we learned how to create a serverless Apollo Server in GraphQL. Now, we will enhance the server by adding a JSON Web Token (JWT) authentication layer. This will allow us to authenticate and authorize requests made to our server.

Prerequisites

Before we begin, make sure you have a basic understanding of Apollo Server, GraphQL, and JSON Web Tokens (JWT).

Step 1: Installing Dependencies

To get started, we need to install the jsonwebtoken package, which provides JWT functionality. Run the following command in your terminal:

npm install jsonwebtoken

Step 2: Importing Dependencies

In the code snippet you provided, we already imported the jsonwebtoken package. If you haven’t done so, ensure that you import it at the top of your file:

import { ApolloServer, BaseContext } from "@apollo/server";
import { startServerAndCreateNextHandler } from "./startServerAndCreateNextHandler";
++ import jwt from "jsonwebtoken";

Step 3: Updating Apollo Context

Next, we need to update the ApolloContext interface to include the necessary properties for authentication:

export interface ApolloContext extends BaseContext {
++  authorization?: string;
++  jwt?: jwt.JwtPayload | null | string;
}

Here, we add the authorization property to hold the JWT token received from the request headers, and the jwt property to store the decoded JWT payload.

Step 4: Decoding JWT Tokens

To decode the JWT token, we’ll create a decode function. Add the following code snippet:

const decode = (token?: string) =>
  jwt.decode(token?.substring(7, token.length) as string);

This function uses the jsonwebtoken package to decode the JWT token. We remove the "Bearer " prefix from the token by using the substring method.

Step 5: Updating Apollo Server Configuration

Now, we’ll update the configuration of the ApolloServer instance to include the JWT authentication logic. Modify the code as follows:

const server = new ApolloServer<ApolloContext>({
  resolvers,
  typeDefs,
  introspection: true,
});

export default startServerAndCreateNextHandler(server, {
  context: async (req, res) => ({
    req,
    res,
++    authorization: req?.headers?.authorization,
++    jwt: decode(req?.headers?.authorization),
  }),
});

In the context function, we assign the authorization property of the ApolloContext based on the value of the authorization header received in the request. We also call the decode function to decode the JWT token and assign it to the jwt property.

Conclusion

In the next part of this tutorial series, we will explore how to implement authorization rules to restrict access to certain parts of your GraphQL schema based on user roles and permissions.

Happy hacking!