Skip to content

Latest commit

 

History

History
 
 

permissions

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Permissions

This example demonstrates how to implement a GraphQL server with authentication and permission rules based on Prisma & graphql-yoga.

For more information on implementing a permissions system with GraphQL, you can also follow this tutorial.

Get started

Note: prisma is listed as a development dependency and script in this project's package.json. This means you can invoke the Prisma CLI without having it globally installed on your machine (by prefixing it with yarn), e.g. yarn prisma deploy or yarn prisma playground. If you have the Prisma CLI installed globally (which you can do with npm install -g prisma), you can omit the yarn prefix.

1. 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/graphcool/prisma/tar.gz/master | tar -xz --strip=2 prisma-master/examples/permissions

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

cd permissions
yarn install

2. Deploy the Prisma database service

You can now deploy the Prisma service (note that this requires you to have Docker installed on your machine - if that's not the case, follow the collapsed instructions below the code block):

yarn prisma deploy
I don't have Docker installed on my machine

To deploy your service to a public cluster (rather than locally with Docker), you need to perform the following steps:

  1. Remove the cluster property from prisma.yml
  2. Run yarn prisma deploy
  3. When prompted by the CLI, select a public cluster (e.g. prisma-eu1 or prisma-us1)
  4. Replace the endpoint in index.js with the HTTP endpoint that was printed after the previous command

3. Start the GraphQL server

The Prisma database service that's backing your GraphQL server is now available. This means you can now start the server:

yarn start

The server is now running on http://localhost:4000.

Testing the API

The easiest way to test the deployed service is by using a GraphQL Playground.

Open a Playground

You can either start the desktop app via

yarn playground

Or you can open a Playground by simply navigating to http://localhost:4000 in your browser.

Note: You can also invoke the yarn dev script (instead of yarn start) which starts the server and opens a Playground in parallel. This will also give you access to the Prisma API directly.

Register users with the signup mutation

You can send the following mutation in the Playground to create a new User node and at the same time retrieve an authentication token for that User:

mutation {
  signup(
    email: "[email protected]"
    password: "graphql"
  ) {
    token
  }
}

If no admin field is set, the role defaults to CUSTOMER. You can create users with the ADMIN role by setting admin to true:

mutation {
  signup(
    email: "[email protected]"
    password: "12345"
    admin: true
  ) {
    token
  }
}

Logging in an existing user with the login mutation

This mutation will log in an existing User node by requesting a new authentication token:

mutation {
  login(
    email: "[email protected]"
    password: "graphql"
  ) {
    token
  }
}

Checking whether a user is currently logged in with the me query

For this query, you need to make sure a valid authentication token is sent along with the Bearer -prefix in the Authorization header of the request. Inside the Playground, you can set HTTP headers in the bottom-left corner:

Once you've set the header, you can send the following query to check whether the token is valid:

{
  me {
    id
    email
  }
}

If the token is valid, the server will return the id and email of the User node that it belongs to.

Change the password with the updatePassword mutation

This mutation changes the password of the authenticated User. Make sure the Authorization header is set:

mutation {
  updatePassword(
    oldPassword: "graphql"
    newPassword: "GraphQL42"
  ) {
    id
  }
}

You can verify the password change by trying the login mutation with the new password.

Admin users can also change the password of other users. Make sure the provided Authorization token is obtained from a login mutation of a User with the ADMIN role (you need to replace the placeholder __USER_ID__ with the id of an actual User):

mutation {
  updatePassword(
    userId: "__USER_ID__"
    newPassword: "test"
  ) {
    id
    email
  }
}

Create posts with the createPost mutation

With this mutation, authenicated users can create a new Post. Make sure the Authorization header is set:

mutation {
  createPost(
    title: "GraphQL is awesome"
  ) {
    id
  }
}

Update posts with the updateTitle mutation

With this mutation users with the default CUSTOMER role can change their own posts (i.e. the one for which they're the author) and users with the ADMIN role can also change posts of other users (replace the __POST_ID__ placeholder with the id of the Post to be updated):

mutation {
  updateTitle(
    id: "__POST_ID__"
    newTitle: "Prisma makes building GraphQL servers a breeze"
  ) {
    title
  }
}

Troubleshooting

I'm getting the error message [Network error]: FetchError: request to http://localhost:4466/permissions-example/dev failed, reason: connect ECONNREFUSED when trying to send a query or mutation

This is because the endpoint for the Prisma service is hardcoded in index.js. The service is assumed to be running on the default port for a local cluster: http://localhost:4466. Apparently, your local cluster is using a different port.

You now have two options:

  1. Figure out the port of your local cluster and adjust it in index.js. You can look it up in ~/.prisma/config.yml.
  2. Deploy the service to a public cluster. Expand the I don't have Docker installed on my machine-section in step 2 for instructions.

Either way, you need to adjust the endpoint that's passed to the Prisma constructor in index.js so it reflects the actual cluster domain and service endpoint.