Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

graphql-shield integration #448

Closed
snys98 opened this issue Oct 20, 2019 · 12 comments
Closed

graphql-shield integration #448

snys98 opened this issue Oct 20, 2019 · 12 comments
Labels
Community 👨‍👧 Something initiated by a community Enhancement 🆕 New feature or request Out of scope ✖️ Proposal doesn't fit in project goals

Comments

@snys98
Copy link

snys98 commented Oct 20, 2019

Is your feature request related to a problem? Please describe.
I'm frustrated when I need to defined a BIG AuthChecker and I need a graphql-shield-like approch to protect my resolvers.

Describe the solution you'd like
Make the Authorized decorator to accept graphql-shield rules and generate appropriate permission tree then apply it to the schema.
Just like this:
image

Describe alternatives you've considered
Here is my workaround approach, but I really hope that there would be a better official approach to model the authentication layer in type-graphql.

Additional context
No additional context so far.

@MichalLytek MichalLytek added Community 👨‍👧 Something initiated by a community Discussion 💬 Brainstorm about the idea Enhancement 🆕 New feature or request Need More Info 🤷‍♂️ Further information is requested labels Oct 21, 2019
@MichalLytek
Copy link
Owner

MichalLytek commented Oct 21, 2019

Have you tried to use just @UseMiddleware for that? It has the same signature as graphql-middleware so you should be able to use graphql-shield easily. @Authorized is just a middleware that use the metadata provided on the field/resolver method, if you don't like this approach you can use your own with middlewares and custom decorators.

@snys98
Copy link
Author

snys98 commented Oct 22, 2019

Well, this is a good idea, and can be done by @UseMiddleware with rules apply in runtime. But my point is that the current @Authorized(roles)&authChecker(func) style authentication is not enough for many situations. And if we consider authentication a part of type-graphql, maybe we should achieve it with a better approach, such as graphql-shield. How do you like it? 😉

@fullofcaffeine
Copy link

style authentication is not enough for many situations

Could you elaborate on why you think it's not enough?

@snys98
Copy link
Author

snys98 commented Oct 23, 2019

Imaging that we have a resource that only available for users not only with role of admin but also another single user or two.
And I prefer the model of RBAC, with concepts of user, role and permission.
image

And with graphql-shield, we can achieve it.

@MichalLytek
Copy link
Owner

But the bulti-in authorization module is not only about the string roles. It's basically storing the metadata you want by calling @Authorized<YourType>() - it can be objects (ACL) or a functions (dynamic rules) too. And a generic auth handler that will receive the resolver data, the metadata from decorator and can calculate the access.

GraphQL shield API is strictly for applying the guard rules on apollo-like resolvers when we have typedefs defined as sdl string. So there's no need for making a wrapper on a wrapper for authorization.

@snys98
Copy link
Author

snys98 commented Oct 24, 2019

hmm...I finally realized...I just got caught into the naming of role and its default implementation of string...Maybe we should change the name of role to permissionIdentifier or some what? or comment it in the docs? Just in case of stupid guys like me. 😭

@MichalLytek
Copy link
Owner

Just always read the docs first - TypeScript definitions are not enough to work with all te features of the new framework 😉

We can leave the @Authorized decorator brackets empty or we can specify the role/roles that the user needs to possess in order to get access to the field, query or mutation. By default the roles are of type string but they can easily be changed as the decorator is generic - @Authorized<number>(1, 7, 22).

https://typegraphql.ml/docs/authorization.html#how-to-use

In the future when #124 comes to live, I will refactor the authorization feature to use it and add an example/tutorial in docs how to create your own authorization layer with custom logic. So closing this issue for now 🔒

@MichalLytek MichalLytek added Out of scope ✖️ Proposal doesn't fit in project goals and removed Need More Info 🤷‍♂️ Further information is requested Discussion 💬 Brainstorm about the idea labels Oct 26, 2019
@Nevon
Copy link

Nevon commented Feb 27, 2020

Does anyone have a working example of using graphql-shield rules in type-graphql, either using @Authorized<IRule> or by applying shield as a global middleware and using custom rule decorators? I've been trying to make it work with the first approach, but am having issues with resolving the rules from within the auth checker.

@Sytten
Copy link

Sytten commented Apr 22, 2020

@MichalLytek Having an example would really help, one advantage of shield is the caching so you don't execute complex checks multiple times.

@omar-dulaimi
Copy link

@snys98 @Sytten @Nevon

// permissions.ts
import { shield, allow, or, and, deny } from 'graphql-shield';

export default shield(
    {
        Query: {
            abuses: deny,
        },
    },
    { debug: true },
);
// index.ts

    import { applyMiddleware } from 'graphql-middleware';

    const schema = await tq.buildSchema({
        resolvers,
    });

    const context = createContext();
    const server = new ApolloServer({
        schema: applyMiddleware(schema, permissions),
        context,
        validationRules,
        formatError,
    });

    server.listen({ port: 4000 }, () => console.log('🚀 Server ready at: http://localhost:4000' );


@omar-dulaimi
Copy link

This line schema: applyMiddleware(schema, permissions), messes up file uploads, so take notice of that.

I kept getting Error: Unknown object type "promise" errors until I removed that line. But now graphql shield won't work like this!

@utkarsh867
Copy link

utkarsh867 commented Aug 19, 2021

I had stumbled on this thread earlier so I decided I might be able to help.

https://github.com/utkarsh867/typegraphql-authchecker

And the package at: https://www.npmjs.com/package/typegraphql-authchecker

Allows to define rules in the Authorized() decorator with conditionals as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community 👨‍👧 Something initiated by a community Enhancement 🆕 New feature or request Out of scope ✖️ Proposal doesn't fit in project goals
Projects
None yet
Development

No branches or pull requests

7 participants