OAuth2 Server route callbacks for use within a Slim 3 Framework API
Chadicus\Slim\OAuth2\Routes requires PHP 5.6 (or later).
To add the library as a local, per-project dependency use Composer! Simply add a dependency on
chadicus/slim-oauth2-routes
to your project's composer.json
file such as:
composer require chadicus/slim-oauth2-routes
Developers may be contacted at:
With a checkout of the code get Composer in your PATH and run:
./composer install
./vendor/bin/phpunit
The authorize
and receive-code
route require view
objects. The given view object must implement a render method such as the one found in slim/twig-view and slim/php-view. It would be best if there was a common ViewInterface
which both implementing but as of now such an interface does not exist.
use Chadicus\Slim\OAuth2\Routes;
use OAuth2;
use OAuth2\GrantType;
use OAuth2\Storage;
use Slim;
use Slim\Views;
//Set-up the OAuth2 Server
$storage = new Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new GrantType\AuthorizationCode($storage));
$server->addGrantType(new GrantType\ClientCredentials($storage));
//Set-up the Slim Application
$app = new Slim\App(
[
'view' => new Views\PhpRenderer('/path/to/chadicus/slim-oauth2-routes/templates'),
]
);
$container = $app->getContainer();
$app->map(['GET', 'POST'], Routes\Authorize::ROUTE, new Routes\Authorize($server, $container['view']))->setName('authorize');
$app->post(Routes\Token::ROUTE, new Routes\Token($server))->setName('token');
$app->map(['GET', 'POST'], Routes\ReceiveCode::ROUTE, new Routes\ReceiveCode($container['view']))->setName('receive-code');
$app->post(Routes\Revoke::ROUTE, new Routes\Revoke($server))->setName('revoke');
//Add custom routes
$slim->get('/foo', function($request, $response, $args) {
$authorization = $request->getHeaderLine('Authorization');
//validate access token against your storage
return $response->withStatus(200);
});
//run the app
$app->run();
Within the Authorization route, you can define a UserIdProviderInterface
to extract the user_id from the incoming request. By default the
route will look in the GET
query params.
class ArgumentUserIdProvider implements UserIdProviderInterface
{
public function getUserId(ServerRequestInterface $request, array $arguments)
{
return isset($arguments['user_id']) ? $arguments['user_id'] : null;
}
}
//middleware to add user_id to route parameters
$loginMiddelware = function ($request, $response, $next) {
// Validate the user credentials
$userId = MyUserService::getUserIdIfValidCredentials($request);
if ($userId === false) {
return $response->withStatus(303);
}
//Put user_id into the route parameters
$route = $request->getAttribute('route');
$route->setArgument('user_id', $userId);
//Credentials are valid, continue so the authorization code can be sent to the clients callback_uri
return $next($request, $response);
};
$authorizeRoute = new Routes\Authorize($server, $view, 'authorize.phtml', new ArgumentUserIdProvider());
$app->map(
['GET', 'POST'],
Routes\Authorize::ROUTE,
$authorizeRoute
)->add($loginMiddleware)->setName('authorize');