Authentication Using Context in Graphql (Part 4)

Authentication Using Context in Graphql (Part 4)

Hello and welcome back once again, to this beautiful series where we are going to explore deeply, what is graphql and how it is been used in today's web development you can read all the articles related to this series by clicking here.

Till now, up to the 3 parts of this series which we have discussed previously, we have learned a lot of things in graphql such as,

  1. Benefits of using Graphql over REST API.

  2. What is typeDefs, resolvers, and input.

  3. What are the queries and mutations in graphql?

  4. What are Aliases, arguments and fragments in graphql?

  5. We have also seen, what are the parameters accepted by resolvers.

  6. How to Set up our graphQL server.

Now, In this article, we will learn more about the Context in graphql and how to use it inside resolvers to provide authentication and authorization.

During a GraphQL operation, you can share data throughout your server's resolvers and plugins by creating an object named contextValue.

Your GraphQL API probably needs to control which users can see and interact with the various data it provides.

In software development, you can control this access of data to the user by using the concept of authentication and authorization, and we can also use this technique in graphql by using contextValue provided by graphql.

Authentication is determining whether a given user is logged in, and subsequently determining which user someone is known.

Authorization is then determining what a given user has permission to do or see.

Putting authenticated user info in your ContextValue:

Whenever we want to restrict the user from accessing certain data, we can authenticate the user in the contextValue, this process of authenticating the user in grapql can be done with multiple techniques but one of the very widely used methods is to provide the including HTTP headers and JSON web tokens.

The example below extracts a user token from the HTTP Authorization header included in each operation request. It then fetches the corresponding user object for that token and adds it to the contextValue Object that's passed to every executing resolver. Each resolver can then use this object to determine what data the user has access to.

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

const { url } = await startStandaloneServer(server, {

  // Note: This example uses the `req` argument to access headers,
  // but the arguments received by `context` vary by integration.
  // This means they vary for Express, Fastify, Lambda, etc.

  // For `startStandaloneServer`, the `req` and `res` objects are
  // `http.IncomingMessage` and `http.ServerResponse` types.
  context: async ({ req, res }) => {
    // Get the user token from the headers.
    const token = req.headers.authorization || '';

    // Try to retrieve a user with the token
    const user = await getUser(token);

    // Add the user to the context
    return { user };
  },

});

console.log(`🚀 Server listening at: ${url}`);

Note: In Graphql, Because your contextValue is generated for every request, you don't have to worry about cleaning the user Data at the end of each operation execution.

From the above code, it is clearly understood that a contextValue is a asynchronous function which returns an object, this object is then accessible to your server's resolver.

How to Utilise this ContextValue in Resolvers:

Since we have created a contextValue function in our server, we can now use this contextValue in the resolver to authenticate the user, Let us see how it is done.

import { GraphQLError } from 'graphql';

const resolvers = {
  Query: {
    // Example resolver
    //we can use contextValue, in third parameter of our resolver
    adminExample: (parent, args, contextValue, info) => {
      if (contextValue.user !== ADMIN) {
        throw new GraphQLError('not admin!', {
          extensions: { code: 'UNAUTHENTICATED' },
        });
      }
      else{
        //You can now allow users to access the data
       }
    },
  },
};

In this way, using the contextValue we can now make our graphql server that has the ability to authenticate and authorize the user with particular access to the data based on eligibility.

Conclusions:

Overall, by reading this article we can clearly understand how to authenticate the user using contextValue and how to create this contextValue function inside our server which will return an object.

I hope you find the article valuable and worth reading to gain some insight about contextValue in graphql, I have learned this topic on the internet and as well as graphQL docs which will be shared below, check out these graphql docs to have a better understanding of the topics.

Did you find this article valuable?

Support Ganesh's Blog by becoming a sponsor. Any amount is appreciated!