Trying to follow along [tutorial](<https://blog.gr...
# orm-help
v
Trying to follow along [tutorial](https://blog.graph.cool/tutorial-building-a-realtime-graphql-server-with-subscriptions-2758cfc6d427) for subscriptions on
prisma
, I have a Subscription resolver that ends up in it's request object being undefined. Has anyone tried Subscription with auth? More details in thread:
Here's some code snippets to illustrate:
Copy code
export const Subscription = {
  result : {
    subscribe(parent, args, ctx: Context, info) {
      if (ctx.request.get('Authorization')) { ... }
      return ctx.db.subscription.result({ where: args.where }, info)
    }
  }
}
That fails at ctx.request being undefined in the playground.
Cannot read property 'get' of undefined
IOW, the context object doesn't have a defined request object at runtime though it does have the db object. I verified this by removing the
ctx.request.get
call above. Note the ctx object type:
Copy code
export interface Context {
  db: Prisma
  request: any
}
Does anyone have experience getting subscriptions to work with authorization? How do I insert auth checking?
w
Hey there. That is because subscriptions aren’t http request, and don’t have the same context. The context of a subscriptions is located here
ctx.connection.context
. Now, in order to pass a context to your subscriptions (using Apollo for example), you need to set the field
connectionParams
when building your
SubscriptionLink
. As for how to pass that authorization token in a middleware way, there’s that issue (https://github.com/apollographql/subscriptions-transport-ws/issues/102), but I haven’t found a way to make it work yet. Looking at how
graphql-playground
works might be a solution though, as the context is properly passed from there.
v
Thanks @weakky. I ended up doing this for now and it's working:
Copy code
export interface Context {
  db: Prisma
  request: any
  connection: {context: any}  //XXX: nasty hack to reuse getUserId() for subscriptions
}
Then locate Authorization header like this:
Copy code
const Authorization = ctx.request ? ctx.request.get('Authorization') : ctx.connection.context.Authorization
before verifying the associated jwt token. Which then lets me keep the call site of the userid checking function in resolvers simple and same across subscription, mutation and query resolver functions:
Copy code
export const Subscription = {
  result : {
    subscribe(parent, args, ctx: Context, info) {
      const id = getUserId(ctx)
      return ctx.db.subscription.result({ where: args.where }, info)
    }
  }
}
Sharing in case this work for others as well.