tuupola / slim-basic-auth

PSR-7 and PSR-15 HTTP Basic Authentication Middleware
MIT License
440 stars 66 forks source link

Inject authorized users inside a route - Database connection defined by parameter #50

Closed rduarte closed 6 years ago

rduarte commented 6 years ago

Hello,

I've an API that needs to set the list of authorized users and passwords in a route because each account has a separate database.

Example:

$app->get('/status/{account}', function ($request, $response, $args) { 
  // connect to account database and check status
  return $response->withJson($data);
});

Is there any way to inject into \Slim\Middleware\HttpBasicAuthentication the list of authorized users and passwords in this context?

Thanks!

tuupola commented 6 years ago

I guess you could either create a custom authenticator or you could use container for setting up the middleware with something like (totally untested code):

use Tuupola\Middleware\HttpBasicAuthentication;
use Tuupola\Middleware\HttpBasicAuthentication\PdoAuthenticator;

$container = $app->getContainer();

$container["HttpBasicAuthentication"] = function ($container) {
    $request = $container["request"];
    $route = $request->getAttribute("route");
    $account = $route->getArgument("account");

    $pdo = new PDO("sqlite:/tmp/{$account}.sqlite");

    return new HttpBasicAuthentication([
        "authenticator" => new PdoAuthenticator([
            "pdo" => $pdo
        ])
    ]);
};

$app->add("HttpBasicAuthentication");

Here are some examples on how to use container for setting up the middleware.

silentworks commented 6 years ago

If that is a middleware please don't get the request from the $container. It is better to do

$container["HttpBasicAuthentication"] = function ($request, $response) {
    $route = $request->getAttribute("route");
    $account = $route->getArgument("account");
    $pdo = new PDO("sqlite:/tmp/{$account}.sqlite");

    return new HttpBasicAuthentication([
        "authenticator" => new PdoAuthenticator([
            "pdo" => $pdo
        ])
    ]);
};

$app->add("HttpBasicAuthentication");
rduarte commented 6 years ago

Hi,

I understood the code but I don't understand where it is placed. Can you help?

My slim-framework index.php:

if (PHP_SAPI == 'cli-server') {
    $url  = parse_url($_SERVER['REQUEST_URI']);
    $file = __DIR__ . $url['path'];
    if (is_file($file)) {
        return false;
    }
}
require __DIR__ . '/../vendor/autoload.php';
session_start();

use \Slim\Middleware\HttpBasicAuthentication\AuthenticatorInterface;
use \Slim\Middleware\HttpBasicAuthentication\PdoAuthenticator;

$pdo = new \PDO("mysql:host=localhost;dbname=brainsoft", "root"," root", array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));

$settings = require __DIR__ . '/../src/settings.php';
$app = new \Slim\App($settings);
$app->add(new \Slim\Middleware\HttpBasicAuthentication([
    "path" => ["/chats"],
    "authenticator" => new PdoAuthenticator([
        "pdo" => $pdo
    ])
]));

require __DIR__ . '/../src/dependencies.php';
require __DIR__ . '/../src/middleware.php';
require __DIR__ . '/../src/routes.php';

$app->run();

Thanks for helping.

tuupola commented 6 years ago

Oh, @silentworks version is much better.

@rduarte You can put it in the place where you setup your middleware. Looking at the example code you pasted most likely src/middleware.php. Note that you should add the HttpBasicAuthentication middleware only once. Remove any old references to it.