php - Laravel 5.4 OAuth 与 Dingo 内部请求

标签 php laravel laravel-5 oauth dingo-api

我正在将 Laravel 5.4 与 Dingo API 一起使用,并且我正在尝试让 Laravel 的 OAuth 2.0(通行证)处理内部 Dingo 请求。以前,我使用的是 JWT,但现在我想使用 OAuth。这是我之前的调度程序代码,它传递所需的 token 以对内部请求执行身份验证。

public function getDispatcher()
{
    $token = JWTAuth::fromUser(Auth::user());
    return $this->api->header('Authorization','Bearer'.$token)->be(Auth::user());
}

现在我正在使用 OAuth 进行身份验证,我的 JavaScript 代码设法通过 passing a cookie using this method 轻松获得身份验证在 JavaScript 中,效果完美。

现在我需要修改 getDispatcher() 方法以获取 Dingo 中“内部请求”的 OAuth token 。有没有人对如何执行此操作有任何提示?理论上我可以为每个用户创建一个个人访问 token ,但这对于内部请求来说似乎有点矫枉过正。任何建议或方法表示赞赏。如何在不通过完整的 OAuth 流程的情况下获取 OAuth token ,或者如何仅针对内部请求关闭身份验证。

根据以下答案更新:

'api.auth' 在路由上独立运行(仅 Dingo)并且内部请求有效。 auth:api (Passport) + api.auth 我得到了内部请求不允许的方法,它以 JSON 形式返回。 {"message":"405 Method Not Allowed"} 现在尝试调用内部 POST 请求时。 (当尝试 POST 到这些路由时,似乎发生了 301 重定向到登录页面,进而导致 API 路径以某种方式变成 GET,从而抛出 405 错误)。

通过 Postman 的 API 请求以相反的方式工作。当两者都处于事件状态时找不到用户 (['middleware' => ['auth:api','api.auth']) 当 (auth:api just Passport) 处于事件状态时它工作正常。

最佳答案

如果我没看错问题,看起来我们正在尝试同时使用两个身份验证提供程序——Dingo's 和 Passport。如果我误解了,请纠正我,但看起来我们实际上不需要在这个项目中同时使用两者。对于大多数应用程序,我们可以使用 Passport 进行身份验证,并将结果简单地传递给 Dingo。

我们通过创建一个 custom authentication provider 来实现这一点将 Dingo 与 Passport 执行的身份验证联系起来:

use Dingo\Api\Contract\Auth\Provider;
use Illuminate\Auth\AuthManager;
...
class PassportDingoAuthProvider implements Provider
{
    protected $guard;

    public function __construct(AuthManager $auth) 
    {
        $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.');
    }
}

如我们所见,上面显示的 Dingo 身份验证提供程序只是挂接到 Laravel 身份验证系统以在身份验证时转发 User。构造函数中指定的'api'守卫应该匹配守卫configured for Passport (我们通常在 config/auth.php 中的 'guards' 数组中添加一个 'api' 条目):

'guards' => [
    ...
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

然后,我们需要在 config/api.php 中向 Dingo 注册自定义提供程序:

'auth' => 
    'passport' => App\Providers\PassportDingoAuthProvider::class
]

现在我们可以声明使用 Passport 身份验证中间件 (auth:api) 和 Dingo 身份验证中间件 (api.auth) 的 protected 路由:

$api->get('endpoint', function () { ... })->middleware('auth:api', 'api.auth');

我们可以创建一个 middleware groupapp/Http/Kernel.php 中,如果需要可以将它们结合起来:

protected $middlewareGroups = [
    ...
    'auth:api-combined' => [
        'auth:api', // Passport
        'api.auth'  // Dingo
    ]
];

当应用程序需要调用内部 API 时,客户端应该已经通过身份验证,因为典型的 Laravel 应用程序在中间件堆栈中处理身份验证。如您所知,如果需要,我们可以简单地将经过身份验证的 User 传递给 Dingo 端点:

return $this->api->be(auth()->user())->get('endpoint');

...但这对于上面显示的身份验证提供程序来说不是必需的。 Dingo 将从 Passport 的 auth guard 解析经过身份验证的用户。

这是a sample project结合了这些概念。

Now that I'm using OAuth to Authenticate, my Javascript code manages to get authentication simply by passing a cookie using this method in the Javascript...I need to modify the getDispatcher method to get the OAuth token on an 'Internal request' within Dingo.

当我们使用 CreateFreshApiToken middleware , Laravel 即时生成加密的 JWT。我们可以手动创建这些 token 之一:

use Firebase\JWT\JWT; // installed with Passport
...
$token = JWT::encode([
    'sub' => auth()->id(),
    'csrf' => session()->token(),
    'expiry' => Carbon::now()->addMinutes(config('session.lifetime')),
], app('encrypter')->getKey());

我们可以看出这不是标准的 OAuth 访问 token ——Passport 仅将这些用于 Web 请求。或者,我们可以从 JavaScript 传回的 cookie 中获取此值:

$token = request()->cookie(Passport::cookie());

但是,如果我们如上所述将 Dingo 与 Passport 集成,则不需要此 token 。

关于php - Laravel 5.4 OAuth 与 Dingo 内部请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47383367/

相关文章:

php - 如何构建查询

php - 导致 sum() 到多个结果的分组表

php - 如何使用 php 使用随机化链接

javascript - 拉维尔 4 : Sidebar is not clickable

php - 使用 laravel 发送电子邮件,但不识别变量

U 盘上的 Laravel Homestead

php - 我怎样才能只运行一次 Laravel 队列?

laravel - 创建或删除关系时如何自动更新父模型的时间戳?

php - 拉维尔 5 : How to handle code that is used in many Controllers

php - 使用脚本在一堆模板中查找函数调用