Sharing Context (ctx) between middleware and policies (and controllers) #6692

This discussion has been migrated from our Github Discussion #6692


romanmandryk190d ago

Hi,
can someone explain differences between middleware and global policy and why aren’t they sharing same ctx object?

  • I need to access to ctx.request.route and ctx.state.user but these are available only in policies (and controllers). I tried to play with the order of middleware but without luck.
  • I need to access ctx.response.body but this is only available in middleware ( after await next() ) and no luck getting it in the policy
  • If I try to set any variable on the context ctx.myVar= 'something' in middleware or policy, it’s undefined in the other. But sharing a variable between different middlewares works fine.
1 Like

Responses to the discussion on Github


marefati110150d ago

in same problem i want access ctx.request.body and ctx.response.body in policy (request by graphql)


lauriejim149d ago

Maintainer

Hello, a policy is in reality a middleware that is apply to defined routes.
And wall just before the controller action.
A middleware is global to the stack, call every times and you can manage the ordre.

After that I just tried that
Path — config/policies/test.js

module.exports = async (ctx, next) => { console.log(ctx.body); await next(); console.log(ctx.body); };

Then I applied it to a find route of my articles collection type and it works well… I’m able to access the data.


romanmandryk148d ago

Author

Thanks @lauriejim for looking in to this.
What you said is probably true only for REST apis, not GraphQL.

After posting this question month ago, I have looked at the code here (+ 3 similar occurences) and found that policies for GraphQL resolvers are only applied before the resolver. For my use case (implementing specific authorization policies ) I had to patch strapi-plugin-graphql like this to run it after the call but it’s far from ideal and the whole resolvers-builder.js file needs to be refactored to run resolver in the middle of the policy/middleware stack, not after it.

I think this is a bug and policies should behave similarly for REST and GraphQL invocations.


lauriejim148d ago

Maintainer

Ping @alexandrebodin about that point.


romanmandryk148d ago

Author

@lauriejim,
another item you haven’t answered is sharing data between policies and middlewares.

If I try to set any variable on the context ctx.myVar= ‘something’ in middleware or policy, it’s undefined in the other. But sharing a variable between different middlewares works fine.

Basically middleware and policies are siloed and can’t share data.


lauriejim148d ago

Maintainer

You can use the ctx.state object to do that.
It’s what we are using to share the authenticated user data across all the middleware stack.