You can find code example for this chapter here.
We've covered access control in the GraphQL Access Control chapter from the viewpoint of the specification. We've seen how entry points and traversals define what data is available for a client and controlling access to the fields as well as the data returned by the resolvers form the basis of security in GraphQL.
In this chapter, we'll dive deep into the implementation of these access control mechanisms and how AppSync supports them. We'll discuss schema directives, data filtering with resolver functions, and best practices.
As a recap, our data model consists of users, articles, and groups. Articles are all public, while users are constrained to their own groups. A special type of users, administrators, can list all users but only in their groups.
type User {
username: String!
friends: [User]
group: Group
}
type Group {
name: String
users: [User]
}
type Article {
text: String
author: User
}
type Query {
user(username: String!): User
allUsers: [User]
allArticles: [Article]
}
The controls we'll implement are:
Query.allUsers
can be called only by administratorsWhen a regular user makes this query, it will be denied:
query MyQuery {
allUsers {
username
}
}
Query.user
can only be called with the current userThis query made by user1
will be denied:
query MyQuery {
user(username: "user1") {
username
}
}
User.group
only works when the caller is in the same groupThis query made by a user in one group will get group: null
for users in a different group:
query MyQuery {
allArticles {
author {
group {
name
}
}
}
}
Query.allUsers
returns only the users in the admin's groupThe result of this query won't contain users in other groups:
query MyQuery {
allUsers {
username
}
}
The first one will use a directive in the schema, while the others require resolver implementations.