"Not Authorised!" on a field make the containing object null
See original GitHub issueFirst of all I think that graphql-shield add a clean, generic and maintainable security layer to graphql. It don’t replace ad-hoc fine-grained security check in some resolver for special cases but make easy to add uniform basic access control on all your schema. So kudos to you!
I’m implementing a field level access policies with graphql-shield but I’m having a strange issue. When a field is “Not Authorised!” the parent object is set to null. Here is an example.
Permissions:
const permissions = shield({ Query: { node: allow, }, User: { name: allow, secret: deny } });
Query:
{ node (id: 'myId') { ... on User { name, secret } } }
Expected result:
{ "data": { "node": { name: "My name" } }, "errors": [ { "message": "Not Authorised!", "locations": [ { "line": 31, "column": 3 } ], "path": [ "node", "secret" ] } ] }
Actual result:
{ "data": { "node": null }, "errors": [ { "message": "Not Authorised!", "locations": [ { "line": 31, "column": 3 } ], "path": [ "node", "secret" ] } ] }
It’s not an errorPolicy issue on the client because this is extracted from the raw http response.
Only parent object is set to null.
A connection query has all fields normally returned but edges are like this
edges { edge { node: null }, edge { node: null }, edge { node: null }, edge { node: null } }
I’d like to adopt graphql-shield so let me know if I can help to solve this issue. Thanks.
Issue Analytics
- State:
- Created 5 years ago
- Comments:10
Top GitHub Comments
Perfect, thank you so much for this input. 🎉
So, the reason you are experiencing this issue has to do with how GraphQL processes responses. I’ll use SDL to present the idea, but I believe you should have no problem translating this into your schema as well.
GraphQL uses strongly typed language. That means that there’s a particular “contract” between client and server which makes sure no result is unpredictable. My thinking is this; if I am querying type book by its
id
and want to accessid
,name
andcontent
field which are all non-nullable I rely on the fact that every single field in a book instance will have value once I get the result. This way, I don’t have to write checks on the frontend to make sure every field, in fact, has a value.Imagine a situation where one of the fields throws an error. In such a scenario, GraphQL can no longer ensure that all fields in
Book
will have a value. Hence, to keep the contract trustworthy, it has to returnnull
.GraphQL Shield works on a similar pattern; If the user has no access to a particular field, we throw an error. Makes sense, doesn’t it? In your specific case, the problem is that
secret
isnon-nullable
field. Taking into consideration the above section, we can easily understand why in case the customer is not authenticated,user
returns null. If it weren’t so, GraphQL would break the contract.My vague remodelling of your schema looks something like this;
Now to fix the error, you’ve probably guessed by now, you have to change
non-null
secret tonullable
secret.I hope this helps you solve the problem! 🙂
PS.: Check out
node
Query field. Can you ensure that there will always be a user no matter theid
?You are right! I missed the not-null. Changing solved it.
Thank you very much!
PS:
node
Query field called with wrongid
returns anot found
graphql error