tuupola/slim-basic-auth
Abandoned PSR-7/PSR-15 middleware providing HTTP Basic Authentication. Originally for Slim but works with any PSR-compatible framework (tested with Slim and Zend Expressive). Configure allowed username/password pairs and protect routes via middleware.
Installation:
composer require tuupola/slim-basic-auth
Basic Usage (Laravel with PSR-7 middleware):
use Tuupola\Middleware\HttpBasicAuthentication;
$middleware = new HttpBasicAuthentication([
'users' => [
'admin' => 'securepassword',
],
]);
Register in app/Http/Kernel.php:
protected $middleware = [
// ...
\App\Http\Middleware\BasicAuth::class,
];
Create a Laravel middleware wrapper:
namespace App\Http\Middleware;
use Closure;
use Tuupola\Middleware\HttpBasicAuthentication;
class BasicAuth
{
public function __construct()
{
$this->middleware = new HttpBasicAuthentication([
'users' => [
'admin' => 'securepassword',
],
]);
}
public function handle($request, Closure $next)
{
return $this->middleware->process($request, new \Slim\Psr7\Response());
}
}
First Use Case: Protect an API route by adding the middleware to a route group:
Route::middleware(['basic.auth'])->group(function () {
Route::get('/api/protected', 'ApiController@protectedMethod');
});
Route::middleware(['basic.auth'])->group(function () {
Route::get('/admin', 'AdminController@dashboard');
Route::post('/admin/settings', 'AdminController@updateSettings');
});
authenticator for database-backed auth.
$middleware = new HttpBasicAuthentication([
'authenticator' => function ($credentials) {
return \App\Models\User::where('username', $credentials['user'])
->where('password', $credentials['password'])
->exists();
},
]);
.env for security.
$middleware = new HttpBasicAuthentication([
'users' => [
'admin' => env('ADMIN_PASSWORD'),
],
]);
$middleware = new HttpBasicAuthentication([
'path' => ['/api', '/admin'],
'ignore' => ['/api/token', '/admin/ping'],
'users' => ['admin' => 'password'],
]);
$middleware = new HttpBasicAuthentication([
'before' => function ($request, $args) {
return $request->withAttribute('authenticated_user', $args['user']);
},
'after' => function ($response, $args) {
return $response->withHeader('X-Auth-User', $args['user']);
},
'users' => ['admin' => 'password'],
]);
$middleware = new HttpBasicAuthentication([
'error' => function ($response, $args) {
$body = json_encode(['error' => $args['message']]);
return $response->withBody(new \Slim\Psr7\Stream($body));
},
'users' => ['admin' => 'password'],
]);
$middleware = new HttpBasicAuthentication([
'secure' => true,
'relaxed' => ['localhost', 'dev.example.com'], // Allow HTTP for these
'users' => ['admin' => 'password'],
]);
Double Slash Bypass:
//api may bypass /api protection due to PSR-7 path normalization.path rules account for edge cases (e.g., /api/*).Plaintext Passwords:
.env or hashed passwords (e.g., password_hash()).HTTPS Misconfiguration:
secure: true exposes credentials over HTTP.Middleware Order:
HttpBasicAuthentication before route handlers to block unauthorized access early.Laravel PSR-7 Integration:
Illuminate\Http\Request, not PSR-7.Custom Authenticator Quirks:
authenticator callback must return bool. Non-boolean values may cause silent failures.'authenticator' => function ($credentials) {
return (bool) \App\Models\User::validate($credentials);
}
Check Headers:
Authorization: Basic ... headers are sent. Use browser dev tools or curl -v.Log Authentication Attempts:
error callback:
'error' => function ($response, $args) {
\Log::warning("Auth failed for {$args['user']}: {$args['message']}");
return $response->withStatus(401);
}
Test Path Matching:
php artisan route:list to confirm protected routes. Test with:
curl -u admin:password http://localhost/api/protected
Validate Hashes:
$2y$... for bcrypt).Database Auth:
PdoAuthenticator for custom queries:
use Tuupola\Middleware\HttpBasicAuthentication\PdoAuthenticator;
$authenticator = new PdoAuthenticator([
'pdo' => \DB::connection()->getPdo(),
'query' => 'SELECT 1 FROM users WHERE username = :user AND password = :password',
]);
Rate Limiting:
throttle middleware to limit failed attempts:
Route::middleware(['throttle:60,1', 'basic.auth'])->group(...);
Multi-Factor Auth (MFA):
before hook to trigger MFA:
'before' => function ($request, $args) {
if (!$request->hasAttribute('mfa_verified')) {
abort(403, 'MFA required');
}
return $request;
}
Dynamic User Lists:
$middleware = new HttpBasicAuthentication([
'users' => \App\Services\AuthService::getUsers(),
]);
PSR-7 Conversion:
Laravel’s Request must be converted to PSR-7 for compatibility. Use a package like fruitcake/laravel-psr7 or write a helper:
use Psr\Http\Message\ServerRequestInterface;
use Fruitcake\Psr7\Laravel\ConvertRequest;
$psr7Request = ConvertRequest::fromLaravel($request);
Middleware Binding: Bind the middleware to routes dynamically:
Route::get('/admin', function () {
return 'Protected!';
})->middleware(BasicAuth::class);
How can I help you explore Laravel packages today?