graphql-nexus / nexus-plugin-prisma

Deprecated
MIT License
831 stars 118 forks source link

Special handling for authenticated users #342

Open tylerjbainbridge opened 4 years ago

tylerjbainbridge commented 4 years ago

Is there any plan to have special support for authenticated users within the nexus API?

I.e. when I create an item with a relation to a user- it’s almost always going to be the currently authenticated user.

So having the user: { connect/create: { id } } argument exposed in the create gql mutation seems like it could have security issues.

Having some sort of logic around an authenticated user being at ctx.user and auto connecting created items (with a user relation) to that would be super useful.

It could be gated behind a flag/config val getAuthUserFromContext or something like that.

Edit: Happy to help plan an API/contribute to a PR.

pierreyves-lebrun commented 4 years ago

Such a feature probably goes beyond the goals of this project.

For handling authentication within graphQL you can use the graphql-shield package which contains an example of how to integrate it with Nexus: https://github.com/maticzav/graphql-shield/tree/master/examples/with-graphql-nexus

tylerjbainbridge commented 4 years ago

I know you can use shield to handle authentication/block certain types, that's not what I'm talking about.

I'm talking about the t.crud.createOneThing(); and t.crud.updateOneThing(); mutations. These are extremely useful, but the default arguments (which allow for creating/connecting users via API) expose a security vulnerability.

So if my app has a route setup like /profiles/:userId- someone could take that userId and mutate that user's data by simply having their id. The vast majority of the time you create/update an object with a relation to a user, it's the currently authenticated user.

I could write a nexus helper to handle this case, but I imagine a lot of people will run into this and first class support would be relatively simple to add.

pierreyves-lebrun commented 4 years ago

I think it would be fairly easy to add such functionality to your app using graphql-shield as you would just need check for a particular field (e.g.: userId), compare it to the context and either reject or pass on the request based of the result.

In my humble opinion, this gets too close to application business logic and should be handled by a middleware like graphql-shield. The prisma team might of course decide otherwise.

I am just thinking of edge cases where exposing the argument is something you actually want to do for particular requests. To me it sounds like the perfect use-case for a middleware.

tylerjbainbridge commented 4 years ago

Ah- I suppose shield could work well there. Perhaps middleware is the way to go, but I have a hunch that a lot of devs will end up cooking up something themselves and this seems like it could be relatively simple to add to the nexus API without creating bloat.

e.g. This could be the API t.crud.createOneThing({ connectToAuthUser: true }); makeSchema({ getAuthUserId: (ctx) => ctx.user.id })

I agree though- this is in a bit of a grey area between business logic and core functionality.