Skip to content

Latest commit

 

History

History
 
 

permissions-with-shield

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Permissions with GraphQL Shield

This example demonstrates how to use the simple and declarative GraphQL Shield library for authorization by protecting mutations and queries from unauthorized access.

Get Started

1. Install the Prisma CLI

The prisma cli is the core component of your development workflow. prisma should be installed as a global dependency, you can install this with npm install -g prisma

2. Download the example & install dependencies

Clone the Prisma monorepo and navigate to this directory or download only this example with the following command:

curl https://codeload.github.com/prismagraphql/prisma/tar.gz/master | tar -xz --strip=2 prisma-master/examples/permissions-with-shield

Next, navigate into the downloaded folder and install the NPM dependencies:

cd permissions-with-shield
yarn install

3. Deploy the Prisma database service

You can deploy locally but for simplicity, use the Prisma free demo server. To deploy your service to a public cluster (rather than locally with Docker), you need to perform the following steps:

  1. Create a .env file and copy over the content of .env.example to it.
  2. Run prisma deploy to create a new Prisma service.
  3. Replace the value of PRISMA_ENDPOINT in your .env file with the URL of your service instance. The URL looks similar to this: https://us1.prisma.sh/your-username-fd2dcf/service-name/stage
  4. Remember to change the APP_SECRET in the .env file too.

3. Explore the API

To start the server, run the following command

yarn start

Open a Playground

The easiest way to explore this deployed service and play with the API generated from the data model is by using a GraphQL Playground.

The fastest way to open one is by going to http://localhost:7200

Testing the flow

Run the following mutation to signup:

mutation signup {
  signup(username: "test", email: "[email protected]", password: "pass") {
    token
    user {
      email
      username
      createdAt
    }
  }
}

You can also login:

mutation login {
  login(email: "[email protected]", password: "pass") {
    token
    user {
      email
      username
      createdAt
    }
  }
}

Adjust the HTTP header with the received token like so:

{
  "Authorization": "Bearer <token>"
}

for example

{
  "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJjamlkN3hmY3RwcXc1MGE5NnBjaDM1dmtuIiwiaWF0IjoxNTI4OTAwNjc3fQ.IqZ94TjeBaeY22y3XtzfK48fUON-IHk6B62C2xQyChs"
}

Try querying for data:

query posts {
  posts {
    content
  }
}

You will get an Not Authorised error. This is because you need to be authorized as a user to read posts. Run the following:

mutation AssignRole {
  assignRole(role: ADMIN, assigneeEmail: "[email protected]") {
    id
  }
}

This will assign the USER role to the just created user.

assignRole mutation is open so you don't lock yourself out of your own system :). This kind of mutation should be restricted to only Admins.

Here is what the restrictions/permissions look like:

const permissions = shield({
  Query: {
    posts: rules.isUser,
  },
  Mutation: {
    createPost: or(rules.isAdmin, rules.isAuthor, rules.isEditor),
    updatePost: or(rules.isEditor, rules.isPostOwner),
    assignRole: rules.isAdmin,
    createRole: rules.isAdmin,
  },
})