Comments (22)
@maticzav can we please keep this open? subscriptions are fundamental to graphql. having this library admit access on subscription level is of paramount importance to quite large audience from apollo/yoga crowds.
isAuthenticate rule is being hit during subscription access evaluation. however no way to whitelist the specific
Error: Not Authorised!
at normalizeOptions (/Users/polfilm/git_madstat/api-apollo/app/node_modules/graphql-shield/src/shield.ts:25:32)
at shield (/Users/polfilm/git_madstat/api-apollo/app/node_modules/graphql-shield/src/shield.ts:43:29)
at Object.<anonymous> (/Users/polfilm/git_madstat/api-apollo/app/src/permissions.js:25:35)
at Module._compile (internal/modules/cjs/loader.js:688:30)
at Module._compile (/Users/polfilm/git_madstat/api-apollo/app/node_modules/pirates/lib/index.js:83:24)
at Module._extensions..js (internal/modules/cjs/loader.js:699:10)
at Object.newLoader [as .js] (/Users/polfilm/git_madstat/api-apollo/app/node_modules/pirates/lib/index.js:88:7)
at Module.load (internal/modules/cjs/loader.js:598:32)
at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
at Function.Module._load (internal/modules/cjs/loader.js:529:3)
So evaluation of authorization is not taken under consideration.
from graphql-shield.
I managed to get ride of this issue in graphql-yoga
the problem is not in the shield library, but in the way to handle the access token
the rule : isAuthenticated in grapql-yoga for example uses the function
export function getUserId(context: Context) {
const Authorization = context.request.get('Authorization')
if (Authorization) {
const token = Authorization.replace('Bearer ', '')
const verifiedToken = verify(token, APP_SECRET) as Token
return verifiedToken && verifiedToken.userId
}
}
it seams that the request property of the context is not accessible from subscriptions
to get the user id you have to use another property which is "connection" the Authorization status can be accessible from it, so this code works fine for me
export function getUserIdForSubscriptions (context : Context) {
const Authorization = context.connection.context.Authorization
if (Authorization) {
const token = Authorization.replace('Bearer ', '')
const verifiedToken = verify(token, APP_SECRET) as Token
return verifiedToken && verifiedToken.userId
}
}
don't forget to declare it in the interface of the context
import { PubSub } from 'graphql-yoga'
import { ContextParameters } from 'graphql-yoga/dist/types'
export const pubSub = new PubSub()
export interface Context {
connection : any
request: any
pubSub : PubSub,
}
export function createContext(request: ContextParameters) {
return {
...request,
pubSub,
db
}
}
hope this will help
from graphql-shield.
I am facing a similar issue. I want to protect subscriptions, but sadly ctx.request
is undefined
here when the connection is made using websockets whilst it works perfectly for queries and mutations.
const rules = {
isAuthenticated: rule()(async (parent, args, ctx, info) => {
return ctx.request.user !== null;
})
};
from graphql-shield.
Due to all these struggles, I rebuilt my app on Rest api which have very good authentication and authorization (Loopback). Later I put GraphQL on top. Feels much better!
from graphql-shield.
Nah, nothing explicit yet. The most accurate we can do right now is soon. π
from graphql-shield.
OMG, I was banging my head why shield doesn't work with subscription.
from graphql-shield.
@maticzav https://github.com/serverwentdown/graphql-shield-subscriptions-test
from graphql-shield.
Hey π,
I believe this issue is not connected with graphql-shield
but rather a design decision in Yoga and Apollo Server.
(**) Notice that the req argument is an object of the shape { request, response, connection } which either carries a request: Request property (when it's a Query/Mutation resolver), response: Response property (when it's a Query/Mutation resolver), or a connection: SubscriptionOptions property (when it's a Subscription resolver). Request is imported from Express.js. Response is imported from Express.js aswell. SubscriptionOptions is from the graphql-subscriptions package. SubscriptionOptions are getting the connectionParams automatically injected under SubscriptionOptions.context.[CONNECTION_PARAMETER_NAME]
https://github.com/prisma/graphql-yoga#constructorprops-props-graphqlserver
PS.: @serverwentdown thank you for the reproduction. I hope this helps you solve your problem π
from graphql-shield.
@maticzav https://github.com/DavyBello/graphql-shield-subscribe-test
Run node index.js
from graphql-shield.
Thanks, itβs always great to get a welcoming feedback from other developers.
Shield does support mutations
as you already mentioned. I am not uterly sure about subscriptions
though. I think there might be a portion which works, but general functionalty is not implemented.
PS.: watch out for the new version which should debut soon as this will be one of the majors in the new release!
from graphql-shield.
Cool. Is there any ETA for the new version? I'm waiting :)
from graphql-shield.
@styk-tv could you compose a small reproduction repository? I believe this might be connected to graphql-middleware
.
isAuthenticate rule is being hit during subscription access evaluation. however no way to whitelist the specific
I am not sure I understand what you mean "however no way to whitelist the specific". Could you elaborate on that so I can better understand the use case?
from graphql-shield.
@bartosz-maciaszek could you compose a short reproduction repository?
from graphql-shield.
"I believe this issue is not connected with graphql-shield but rather a design decision in Yoga and Apollo Server."
This is like saying universe is flawed for producing gravity hence instead of putting steat belts in a car we will wait for laws of physics to change.
Subscriptions must be adressed. Until then, this bug should remain open.
from graphql-shield.
@styk-tv I am not sure youβve read the entire issue.
from graphql-shield.
I believe there are two different issues here.
The first @bartosz-maciaszek pointed out about the ctx.request being undefined has nothing to do with this library.
Apollo server provides a way to handle it with a combination of the 'subscriptions.onConnect' and 'context' options in the constructor.
The issue I'm currently facing is the rule isn't fired when the subscribe function is run.
Like it's bypassing the middleware entirely but only when running subscriptions.
from graphql-shield.
Could someone provide reproduction for the second case? I am not sure whether this has been addressed in the thread.
from graphql-shield.
i like what you done so far but it will be an excellent if there are to handle authorization for subscriptions with this repo
from graphql-shield.
So can this lib used for subscriptions? And if yes, with what server or setup?
from graphql-shield.
I believe there are two different issues here.
The first @bartosz-maciaszek pointed out about the ctx.request being undefined has nothing to do with this library.
Apollo server provides a way to handle it with a combination of the 'subscriptions.onConnect' and 'context' options in the constructor.The issue I'm currently facing is the rule isn't fired when the subscribe function is run.
Like it's bypassing the middleware entirely but only when running subscriptions.
@navigui
What about this?
from graphql-shield.
Resurrecting this topic since I think I have a fix... for not wrapping the subscription with a rule, not the "missing context" - as others have said that issue is not related to graphql-shield, it's just a matter of making sure context is set for the websocket server (graphql-ws, etc), not just the ApolloServer.
The issue in fact is not even with graphql-shield, it's in graphql-middleware. Basically applyMiddlewareToField() checks for a "resolve" field before it checks for a "subscribe" field, and if there is a resolve it just applies middleware to it and not the subscribe. This does mean that currently it protects the resolver with the net effect that if it fails a rule it will send a subscription event back to the client with "null" for the data field, which is probably not what anyone would want.
When I swapped the order to check for subscribe first, it applied the middleware (and thus the rule checking) to subscribe instead of resolve. (the effect is then to return null instead of an AsyncIterator when a rule fails, which at least with graphql-ws will cause a fatal error and close the websocket... so if that's not desired there is a bit of additional work to handle that but that's not related to graphql-shield, it's just graphq-ws error handling).
So, I'm not quite sure what people feel like the "correct" behavior should be - should it wrap only subscribe, or subscribe and resolve? Note also that checking fields of any returned type works in either case - ie it will still return null for fields that are not allowed, or null for the whole type if a nonnull field is not allowed.
I think either fix is simple - to wrap only "subscribe" it's trivial, just put that check first (shouldn't affect queries or mutations since they can't have a subscribe field). To wrap both is a bit more code to rework applyMiddlewareToField to wrap BOTH subscribe and resolve if they are both present, but still straightforward.
from graphql-shield.
I've created a PR for graphql-middleware based on another's suggested patch:
dimatill/graphql-middleware#569
from graphql-shield.
Related Issues (20)
- Add the ability to use Fragments and post-execution rules with the single server/schema
- Add Typescript typings to rule args
- Add the ability to attach rules using GraphQL Directives
- CI: add codecov reports
- Provide a way to expose authorization metadata through the graphql schema
- GraphQL Shield Roadmap
- 7.6.4 ESM build broken HOT 5
- Documentation website down HOT 1
- How to use `if` condition in GraphQL Shield HOT 2
- Shield rules type generation based on schema HOT 1
- Feature request: wildcard functionality for field names
- Update [email protected] module to avoid @types/lodash and babel runtime in production deps
- fallbackError loses custom error types
- fallbackRule context information HOT 2
- Question: Is there a way to return objects on rules?
- ..
- Typo in the Docs
- Shield permissions only working properly with 'debug: true' HOT 1
- Performance -- every field wrapped is unnecessarily wrapped in a promise HOT 1
- Documents are not populated when running `graphql-shield`, thus leading to `undefined` permission errors.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphql-shield.