# How to create GraphQL API with authorization only on certain queries/mutations?

**URL:** <https://forum.serverless.com/t/how-to-create-graphql-api-with-authorization-only-on-certain-queries-mutations/13593>\
**Category:** Serverless Framework\
**Tags:** lambda\
**Created:** [January 5, 2021, 7:46am UTC](https://forum.serverless.com/t/how-to-create-graphql-api-with-authorization-only-on-certain-queries-mutations/13593 "2021-01-05T07:46:43Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![ryosuke](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/ryosuke/32/4992_2.png) [@ryosuke](https://forum.serverless.com/u/ryosuke)\
**Post date:** [January 5, 2021, 7:46am UTC](https://forum.serverless.com/t/how-to-create-graphql-api-with-authorization-only-on-certain-queries-mutations/13593/1 "2021-01-05T07:46:43Z")

</div>

I’ve been writing a GraphQL API using the Serverless Framework and apollo-server-lambda, and was wondering if there was a good way to only have authorization enabled on certain queries and mutations.

On a REST API it’s possible to include something like `authorizer: aws_iam` inside of the serverless.yml file, but since with GraphQL there’s only one endpoint, the following configuration seems like the only option if you want to allow unauthenticated requests.

```auto
functions:
  graphql:
    handler: graphql.handler
    events:
      - http:
          path: graphql
          method: get
          cors: true
      - http:
          path: graphql
          method: post
          cors: true

```

As a workaround, I’m sending the JWT tokens directly within GraphQL and verifying them within the Lambda function, but I’m wondering if there’s a simpler solution for this. This, for example, is the query that the client can call to show see what items the user has added to their list.

```auto
type ListEntry {
  userId: String!
  itemId: String!
  createdAt: String!
}

type Query {
  listEntries(userId: String!, accessToken: String!): [ListEntry]
}

```

And the resolver is written as follows.

```auto
import AWS from 'aws-sdk'
const dynamoDB = new AWS.DynamoDB.DocumentClient()

const resolvers = {
  Query: {
    listEntries: async (
      _: any,
      { userId, accessToken }: { userId: string; accessToken: string }
    ): Promise<ListEntry[]> => {
      const tokenIsValid = await verifyToken(userId, accessToken)
      if (!tokenIsValid) {
        throw new AuthenticationError('JWT token does not match user ID.')
      }

      const params = {
        TableName: process.env.listEntryTableName as string,
        KeyConditionExpression: 'userId = :userId',
        ExpressionAttributeValues: {
          ':userId': userId
        }
      }
      const res = await dynamoDB.query(params).promise()
      return res.Items as ListEntry[]
    }
  }
}

```

Where the function `verifyToken` is

```auto
import AWS from 'aws-sdk'
const cognito = new AWS.CognitoIdentityServiceProvider()

export const verifyToken = async (
  userId: string,
  accessToken: string
): Promise<boolean> => {
  const params = {
    AccessToken: accessToken
  }
  const user = await cognito.getUser(params).promise()
  return user.Username === userId
}

```

What’s the best way to go about doing this? When I Google this, all I seem to get is solutions using AWS AppSync, which is not what I want. Thanks!
