发现一处问题,如果把修改话题的路由放入不需要 token 验证的接口组里面,就不能通过 $this->authorize () 授权,怎么回事?

如题,按教程走是完全没有问题的,但是如果我故意将修改话题的路由放入不需要token验证的接口组里面,如下

 $api->group([
        'middleware' => 'api.throttle',
        'limit'      => config('api.rate_limits.common.limit'),
        'expires'    => config('api.rate_limits.common.expires'),
    ], function($api) {
        //不需要token验证的接口
       .
       .
        $api->patch('topics/{topic}', 'TopicsController@update')->name('api.topics.update');

即不按教程的要求放入

$api->group([
            'middleware' => 'api.auth',
        ], function($api) {
        //需要token验证的接口
           $api->patch('topics/{topic}', 'TopicsController@update')->name('api.topics.update');

就产生授权无法通过的情况,截图如下:
file

file

这点令我非常困惑,难道$this->authorize()的授权验证,需要'api.auth'这个中间为前置条件?请各位前辈不吝赐教

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
ibucoin
最佳答案

之前对于代码稍微看了一下,你看一下update方法里面,会自动获取当前的$user,而这个$user的话,主要是通过auth来进行获取的,没有通过api.auth的话,自然也无法获取到正确的$user,应该就是这么一个流程。
如果要再深入的话,得去看一下源代码的具体调用。

5年前 评论
讨论数量: 5
ibucoin

之前对于代码稍微看了一下,你看一下update方法里面,会自动获取当前的$user,而这个$user的话,主要是通过auth来进行获取的,没有通过api.auth的话,自然也无法获取到正确的$user,应该就是这么一个流程。
如果要再深入的话,得去看一下源代码的具体调用。

5年前 评论

谢谢你的解答,看来通过auth:api或者api.auth路由中间件确实是策略类进行授权判断的一个前置条件

5年前 评论

以后就要对这两个中间件进行捆绑式的写法了,不能单独使用授权策略了

file

5年前 评论
pardon110

授权判断本质通常都是将当前用户的标识,与资源关联的用户标识比较,相同则通过。对于使用jwt为api驱动的guard而言,你不用那个是中间件,框架获取不到当前用户的标识id(一边无值,一边有值),自然不通过。简单而言,你的这种操作想通过,只要保证操作的话题关联用户标识user_id为空就行了。

5年前 评论
  • 首先将路由不设置api.auth中间件,可以发现无法获得当前user,Trace如下:
    Illuminate\Auth\SessionGuard->user()
    Illuminate\Auth\Access\Gate->resolveUser()
    Illuminate\Auth\Access\Gate->raw()
    Illuminate\Auth\Access\Gate->authorize()
    App\Http\Controllers\Api\TopicsController->authorize()
    App\Http\Controllers\Api\TopicsController->update()
  • 而如果设置了api.auth中间件,就会先进行token验证,验证成功的同时就把user返回了,后面再去判断$this->authorize () 时,就会有当前的user对象了。。
  • api.auth中间件运行步骤:

    • \Dingo\Api\Http\Middleware\Auth::handle调用了$this->auth->authenticate($route->getAuthenticationProviders());
    • \Dingo\Api\Auth\Auth::authenticate调用了$user = $provider->authenticate($this->router->getCurrentRequest(), $this->router->getCurrentRoute());
    • \Dingo\Api\Auth\Provider\JWT::authenticate就是获取token,并进行token验证,成功返回user,否则抛出异常。

      //Authenticate request with a JWT. If success, get the current user.
      public function authenticate(Request $request, Route $route)
      {
          $token = $this->getToken($request);
      
          try {
              if (! $user = $this->auth->setToken($token)->authenticate()) {
                  throw new UnauthorizedHttpException('JWTAuth', 'Unable to authenticate with invalid token.');
              }
          } catch (JWTException $exception) {
              throw new UnauthorizedHttpException('JWTAuth', $exception->getMessage(), $exception);
          }
      
          return $user;
      }
5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!