This example demonstrates how to use the simple and declarative GraphQL Shield library for authorization by protecting mutations and queries from unauthorized access.
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
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
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:
- Create a
.env
file and copy over the content of.env.example
to it. - Run
prisma deploy
to create a new Prisma service. - 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
- Remember to change the
APP_SECRET
in the.env
file too.
To start the server, run the following command
yarn start
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
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,
},
})