Laravel 5.2 如何将中间件参数传递到服务提供者中的服务容器注册方法?

3
我似乎遇到了一个循环依赖的问题。我们有一个服务提供者,它向服务容器注册一个对象,并引导配置文件和一些中间件。但是现在中间件需要在实例化之前从请求JWT令牌中解析出一个参数并将其传递给服务容器,以及用户的保护程序,因为服务提供者需要能够获取经过身份验证的用户,而有5种不同的类型(申请人、经理、管理员等),因此需要使用保护程序来Auth::guard($guard)->getUser(),因为它会默认设置为Applicant,如果为null,则像Auth::guard()->getUser()一样。

如何解决这个问题?如果有帮助的话,我正在使用tymons/JWTAuth(develop)分支来利用Laravel的保护API。

  1. 我应该重构并直接绑定到中间件中的服务容器,而不使用服务提供者,这样我就可以使用参数来实例化服务容器对象和保护程序。似乎是唯一可能的解决方案,但在我重构所有内容之前,我想问是否有更好的方法。

  2. 我可以使用两个服务提供者吗?一个添加中间件,另一个延迟注册对象到服务容器中?如果可以,你会如何在配置中传递参数?根据我所知,这似乎是不可能的。

为对象添加setter不是一个选项,以防止任何人在其他地方意外调用它。

1个回答

0
你是否正在使用 tymon/jwt-auth?如果是的话,你的服务提供商可以设置一个事件监听器,在令牌解码时触发。类似这样:
event()->listen('tymon.jwt.valid', function($user){
  app()->singleton(YourInterface::class, function() use ($user){
    //this will only register once your token is decoded
  }
});

即使您不使用此软件包,仍可以监听事件,然后绑定触发一次。这与您的选项1基本相同,但至少它可以将代码组织在您想要的位置。


我正在使用tymon/jwt-auth。所以你添加的事件绑定是在服务提供者的启动中吗?使用event()->listen还是$this->app['Event']->listen更好,这只是个人偏好吗?我现在会尝试一下。 - mtpultz
1
是的,有几种语法可以用于绑定事件,它们都应该有效。您还可以创建一个监听器并将其放入EventServiceProvider中的数组中。 - Jeff
@mtpultz 您可以添加另一个中间件或复制现有的中间件以添加自己的自定义事件。 - Jeff
5.x维基的下一节说它具有与上面相同的事件。虽然我还没有查看源代码,所以无法确认。无论如何,我认为绑定事件监听器是您想要采取的路线。希望能有所帮助! - Jeff
我暂时注释了引导程序,推迟了服务提供者,手动添加了中间件,并且在每个请求中设置了配置项以存储用户ID和守卫,这样当服务容器实例化时,我可以调用 Auth::guard($guard)->getUser() 。 - mtpultz
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接