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!