Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 拉拉维尔野狗/api-使用带护照的内部路线(L6)_Php_Laravel_Authentication_Laravel Passport_Dingo Api - Fatal编程技术网

Php 拉拉维尔野狗/api-使用带护照的内部路线(L6)

Php 拉拉维尔野狗/api-使用带护照的内部路线(L6),php,laravel,authentication,laravel-passport,dingo-api,Php,Laravel,Authentication,Laravel Passport,Dingo Api,我看到相当多的人对此有类似的问题,但没有最终解决方案。我已经试着让它工作了大约24小时,但仍然没有运气 目标 使用Laravel 6和Dingo API构建和API 能够在外部使用API,使用Passport oAuth进行身份验证 能够通过ajax,使用passports自认证功能在内部使用API 能够使用dingo的自我消费方法,使用PHP在内部消费API 到目前为止我发现了什么 验证提供程序顺序 我看到的大多数解决方案都建议将passport auth和dingo同时设置。这是auth:a

我看到相当多的人对此有类似的问题,但没有最终解决方案。我已经试着让它工作了大约24小时,但仍然没有运气

目标
  • 使用Laravel 6和Dingo API构建和API
  • 能够在外部使用API,使用Passport oAuth进行身份验证
  • 能够通过ajax,使用passports自认证功能在内部使用API
  • 能够使用dingo的自我消费方法,使用PHP在内部消费API
  • 到目前为止我发现了什么 验证提供程序顺序 我看到的大多数解决方案都建议将passport auth和dingo同时设置。这是
    auth:api
    (passport)和
    api.auth
    (dingo)

    这里的
    api.auth
    实际上是在laravel中设置的自定义身份验证提供程序,配置为dingo,它将passport逻辑连接到dingo

    // Auth provider
    class DingoPassportAuthProvider extends Authorization
    {
        protected $guard;
    
        public function __construct(AuthManager $auth)
        {
            dump('DingoPassportAuthProvider Instantiated');
            $this->guard = $auth->guard('api');
        }
    
        public function authenticate(Request $request, Route $route)
        {
            if ($this->guard->check()) {
                return $this->guard->user();
            }
    
            throw new UnauthorizedHttpException('Not authenticated via Passport.');
        }
    
        public function getAuthorizationMethod()
        {
            return 'Bearer';
        }
    }
    
    如果我们将dingo API提供程序放在中间件堆栈的第一位,我们会得到:

    • 如果使用be()方法指定调用的用户:
      $this->API->be($request->user())->get('/API/profile')

    • 外部API请求和内部AJAX请求正确地进行身份验证,用户从自定义dingo身份验证提供程序返回,但是,由于某些原因,您无法从API控制器中访问此用户:
      $user=$request->user();//空

    如果我们将Passport API提供程序放在中间件堆栈的第一位,我们会得到:

    • 内部API请求根本不起作用(401始终返回)

    • 外部API请求和内部AJAX请求按预期工作

    • 不再调用dingo passport提供程序上的
      authenticate
      方法。我认为这可能与内部电话返回的401有关

    我认为正确的方法是把护照认证放在第一位。通过这种方式,我们在调用dingo身份验证之前对用户进行身份验证,结果有两件事:

  • Passport按预期在本地工作

  • Dingo内部API调用现在应该可以使用
    $this->API->get('/API/profile')
    调用(省略使用
    be()
    定义用户),但是这不起作用

  • 目前我有以前的配置。Passport的工作原理与外部和ajax调用相同,但内部dingo调用始终返回401


    我已经签出了一些样板模板,它们似乎没有什么不同。我想知道L6中是否发生了一些变化来解释为什么内部请求不起作用。

    我现在找到了一个解决方案,大部分方法都是这样的

    在自定义dingo身份验证提供程序中:

    class DingoPassportAuthProvider extends Authorization
    {
        public function authenticate(Request $request, Route $route)
        {
            if (Auth::guard('web')->check()) {
                return Auth::guard('web')->user();
            }
    
            if (Auth::guard('api')->check()) {
                $user = Auth::guard('api')->user();
                Passport::actingAs($user);
    
                return $user;
            }
    
            throw new UnauthorizedHttpException('Not authenticated via Passport.');
        }
    
        public function getAuthorizationMethod()
        {
            return 'Bearer';
        }
    }
    
    现在检查请求是否来自web guard(内部请求)或api guard(外部或ajax请求),并返回正确的用户

    对于api guard,似乎存在一个问题,即用户已通过身份验证,但在控制器中实际不可用。为了解决这个问题,我添加了
    Passport::actingAs($user)
    。这可能不是最好的做法,但是守卫们现在正在按照他们应该的方式行动,就像我所有的不同场景一样

    然后在API路由中间件中,我们只指定定制的dingo提供者

    // API route middleware
    $api->group(['middleware' => 'api.auth'], function (Router $api) {
    ...
    
    需要注意的一点是,dingos
    be()
    方法并不像预期的那样工作。相反,你需要像在普通laravel应用程序中那样切换用户

    \Auth::loginUsingId(2);
    $user = $this->api->get('/api/profile');
    
    // API route middleware
    $api->group(['middleware' => 'api.auth'], function (Router $api) {
    ...
    
    \Auth::loginUsingId(2);
    $user = $this->api->get('/api/profile');