5 ms·
My main concern with GraphQL is access control. What happens if the user doesn't have access to part of the requested data (a subtree)... Will the GraphQL engin
by jondubois 9y ago
My main concern with GraphQL is access control. What happens if the user doesn't have access to part of the requested data (a subtree)... Will the GraphQL engine return an incomplete result, an inline error or will the whole query fail? What if you only want to allow showing specific fields of a resource; for example when a user requests for another user's account details, we need a way to block them from getting certain fields like passwords or keys that might be attached to the account.
How does this access control play with cache? What happens when the access control rules change?
A while ago, I wrote a real-time REST-based plugin which solves all the problems and I use it in production, it's much simpler than GraphQL. See https://github.com/SocketCluster/sc-sample-inventory https://github.com/SocketCluster/sc-sample-inventory
I'm surprised that more libraries aren't following the REST-based model.
- stingraycharles 9y agoWe let our GraphQL server accept a JWT authorization header, which is then propagated to all service calls it does. When the user doesn't have permission to some (sub)resources being requested, the GraphQL server doesn't see it either.
- k__ 9y agoBut what comes back? Lets say I request a user, his name, email and all their friends. But I don't have access to the friends. Now do I get nothing back and the error that my request would include data I have no access to? Or would I get name and email, but the list of friends would be empty? would I get an additional warning somewhere so I know it's an permission problem and the user doesn't have no friends? Would I get an inline error in the place of the friends?
- cheald 9y agoThat's entirely up to you and how you choose to implement your fields' resolutions.
- k__ 9y agoAre there any best practices?
- cheald 9y agoI don't know if there are for GraphQL in particular. I have my GraphQL implementation as a part of a Ruby app. graphql-ruby has this handy error handling doc: https://github.com/rmosolgo/graphql-ruby/blob/master/guides/queries/error_handling.md https://github.com/rmosolgo/graphql-ruby/blob/master/guides/... and there's the graphql-errors gem which sort of does this in a generic manner, allowing individual fields to fail without the whole query failing: https://github.com/exAspArk/graphql-errors https://github.com/exAspArk/graphql-errors
- andrewingram 9y agoModel access control into the schema. Create a BaseUser type and an UnauthorizedAccess type, then a union of the two, refer to the union in nearly all scenarios where you want to create a relationship to a User. GraphQL gives you access to a relatively powerful (but sadly incomplete) type system, you have a much better time if you take full advantage of it.
- schickling 9y agoWhich features are you missing in GraphQL's type system?
- andrewingram 9y agoUnions on scalars, unions on input types, intersection types, and generics. Arrays are already a generic type, but we're unable to create new ones.
- nijynot 9y agoThe solution for authorization/access control is to use "Dataloader" [1] which is also made by Facebook. You write a single source of truth for how authorization is handled, and make sure that graphql resolves with this source. Dataloader is not as well known as GraphQL, but crucial for complex authorization systems imo. It also has a bunch of other features like batching and caching which makes your life easier when opting for this solution. [1]: https://github.com/facebook/dataloader https://github.com/facebook/dataloader
- mxstbr 9y agoI've only ever seen DataLoader used for batching database queries, how do you create a single source of truth for authorization with it? Do you have a code snippet somewhere?
- nijynot 9y agoCheck out this article [1] (or video) on Dan Schafer's talk, on how they use Dataloader and GraphQL internally at Facebook. Covers most of it. To summarize, they create a class for each GraphQLType which has their own "gen" function such that it is the only way to generate data. This way you get a single source of truth. There's also a video of Lee Byron going through Dataloader's source code which was pretty fun to watch. [1]: https://dev-blog.apollodata.com/graphql-at-facebook-by-dan-schafer-38d65ef075af https://dev-blog.apollodata.com/graphql-at-facebook-by-dan-s...
- djmashko2 9y agoHi, author of the post here! With GraphQL, you can think of each field as a tiny endpoint, and you do access control on that in the same way as before. It turns out that while GraphQL allows the frontend developers to select the data they need, that doesn't result in an unlimited set of queries. You often get a number of queries which is similar to what you would get if you hand-coded specific endpoints for different UI views, which turns out to be a common pattern outside of GraphQL. > What happens if the user doesn't have access to part of the requested data In this case, the gateway just falls back to the underlying server implementation, and it's a cache miss.
- otto_ortega 9y ago> It turns out that while GraphQL allows the frontend developers to select the data they need, that doesn't result in an unlimited set of queries. Could you please elaborate on that? Im new to GraphQL and I assumed that you only have to provide it with a schema that defines entities and their relations and it will let you query any combination over it. Does queries have to be explicitly set on the server? As an example, if I have the table "doctors" that has a 1:n relationship with the table "patients", do I have to explicitly define something like: queryDoctors { id name patients { id name } } To be able to query a doctor's patients?
- dudul 9y agoAccess control and permissions shouldn't be part of your API implementation, either REST or GraphQL. It should be part of your business logic so it can be shared regardless of which API protocol you put on top of it.
- jrs95 9y agoYou could do pretty much any of the things you describe, actually. Auth is really not straightforward at all though, they could definitely do a better job at making it easier to get started with GraphQL.