I use Laravel 5.3 with Dingo API, and I'm trying to get Laravel's OAuth 2.0 (aka Passport) to work with Dingo's Authentication.
I added the OAuth 2.0 provider in config/api.php
, which I found here:
'auth' => [
'oauth' => function($app) {
$provider = new Dingo\Api\Auth\LeagueOAuth2Provider($app['oauth2.resource-server']);
$provider->setUserCallback(function($id) {
return User::find($id);
});
$provider->setClientCallback(function($id) {
return Client::find($id);
});
return $provider;
}
]
And then I added the api.auth
middleware onto my route:
$api = app('Dingo\Api\Routing\Router');
$api->version('v2', function($api) {
# ...
$api->get('test', ['middleware' => 'api.auth', 'App\Http\Controllers\v2\SnippetController@test']);
});
And when request the /api/test
, I get a 500
HTTP response with this error:
Call to undefined method Closure::authenticate()
The full JSON response (which includes the trace) can be found here
Sadly the docs barely mention setting up Dingo with league/oauth2-server
, which is what Laravel uses
I had to create a new provider on app/Providers/PassportDingoProvider.php
with the following code:
<?php
namespace App\Providers;
use Dingo\Api\Routing\Route;
use Illuminate\Http\Request;
use Illuminate\Auth\AuthManager;
use Dingo\Api\Auth\Provider\Authorization;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
class PassportDingoProvider extends Authorization
{
/**
* Illuminate authentication manager.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $auth;
/**
* The guard driver name.
*
* @var string
*/
protected $guard = 'api';
/**
* Create a new basic provider instance.
*
* @param \Illuminate\Auth\AuthManager $auth
*/
public function __construct(AuthManager $auth)
{
$this->auth = $auth->guard($this->guard);
}
/**
* Authenticate request with a Illuminate Guard.
*
* @param \Illuminate\Http\Request $request
* @param \Dingo\Api\Routing\Route $route
*
* @return mixed
*/
public function authenticate(Request $request, Route $route)
{
if (! $user = $this->auth->user()) {
throw new UnauthorizedHttpException(
get_class($this),
'Invalid API token'
);
}
return $user;
}
/**
* Get the providers authorization method.
*
* @return string
*/
public function getAuthorizationMethod()
{
return 'Bearer';
}
}
And then I added this in config/api.php
:
'auth' => [
'custom' => \App\Providers\PassportDingoProvider::class
]
Later on, I was able to use the api.auth
Middleware to authenticate my routes.
You can also get the user via Auth::guard('api')->user()
instead of Auth::user()