You can find code example for this chapter here.
So far we've talked about why access control is important for subscriptions, but we haven't looked into how to implement it. For this, we'll use a simple setup with 3 users in 2 different groups and we'll make sure that each user can only get events from its own group but not from the other group.
For subscription events, we'll use the example from the previous chapter where there is a todo
subscription that gets a userId
and a groupId
argument.
type TodoEvent {
userId: ID!
groupId: ID!
todoId: ID!
todo: Todo
}
type Subscription {
todo(userId: ID, groupId: ID): TodoEvent
@aws_subscribe(mutations: ["notifyTodo"])
}
To secure this subscription, we'll need to implement a couple of restrictions:
userId
or the groupId
argument is requireduserId
must be in the same group as the caller UsergroupId
must be the caller's groupEverything related to subscriptions is implemented in the response mapping template for the subscription field's resolver. So every code we write will be for the Subscription.todo
field.
We'll cover a universal approach based on validating the arguments that works with any filtering method, then we'll see a different way that require enhanced filtering.
The idea behing this access control implementation is to check the arguments the client sent and reject the subscription if it is for events that should not be sent to that client. In our example, if the clients sends a subscription with a different group, then it should be rejected.
For example, let's log in with user1
, which is in group1
(the password is Password.1
):
Then a subscription with groupId: "group2"
:
subscription MySubscription {
todo(groupId: "group2") {
todoId
userId
groupId
}
}
The subscription is rejected: