Using Basic Authorization as Middleware PSR-7 PSR-15

Viewed 955

TD;LR: I'm trying to grasp the idea behind middleware implementation. It appears to be working but how do I properly handle the response so it shows a Basic Authorization login prompt to the browser?

--

I'm using:

Running the code below:

$middleware = [
    new \Middlewares\ResponseTime(),
    (new \Middlewares\BasicAuthentication([
        'username1' => 'password1',
        'username2' => 'password2'
    ]))->attribute('username')
];

// Default handler for end of collection
$default = function (\GuzzleHttp\Psr7\ServerRequest $request) {
    // Any implementation of PSR-7 ResponseInterface
    return new \GuzzleHttp\Psr7\Response();
};

$collection = new \Equip\Dispatch\MiddlewareCollection($middleware);

// Any implementation of PSR-7 ServerRequestInterface
$request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals();
$response = $collection->dispatch($request, $default);

print_r($response);

Returns the following:

GuzzleHttp\Psr7\Response Object
(
    [reasonPhrase:GuzzleHttp\Psr7\Response:private] => Unauthorized
    [statusCode:GuzzleHttp\Psr7\Response:private] => 401
    [headers:GuzzleHttp\Psr7\Response:private] => Array
        (
            [WWW-Authenticate] => Array
                (
                    [0] => Basic realm="Login"
                )

            [X-Response-Time] => Array
                (
                    [0] => 16.176ms
                )

        )

    [headerNames:GuzzleHttp\Psr7\Response:private] => Array
        (
            [www-authenticate] => WWW-Authenticate
            [x-response-time] => X-Response-Time
        )

    [protocol:GuzzleHttp\Psr7\Response:private] => 1.1
    [stream:GuzzleHttp\Psr7\Response:private] => 
)

It appears middlewares/response-time and middlewares/http-authentication were executed just fine. However, I am under the impression that middlewares/http-authentication will show an actual login prompt like this:

enter image description here

But it didn't. I am suppose to implement that myself? If yes, how can I do that properly?

1 Answers

Please change the realm to 'My realm'.

$middleware = [
    new \Middlewares\ResponseTime(),
    (new \Middlewares\BasicAuthentication([
        'username1' => 'password1',
        'username2' => 'password2'
    ]))->attribute('username')->realm('My realm')
];

The GuzzleHttp request happens in the backend so it won't work like it normally would work in a browser e.g. prompting for username and password. You are basically imitating a request when you use Guzzle without using any browsers. As such if you want the prompt you will have to implement this logic without using GuzzleHttp.

You can still test it with Guzzle as per below.

The below code will work.

$request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals()->withHeader('Authorization', 'Basic '.base64_encode('username1:password1'));
$response = $collection->dispatch($request, $default);
echo $response->getStatusCode(); //200
echo $response->getReasonPhrase(); // OK

The below code will fail.

$request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals()->withHeader('Authorization', 'Basic '.base64_encode(''IncorrectUser:IncorrectPassword''));
$response = $collection->dispatch($request, $default);
echo $response->getStatusCode(); //401
echo $response->getReasonPhrase(); // Unauthorized

The best way to implement the BasicAuthentication would be within a middleware framework.

Zend Expressive

   //Example using your library
   $app->pipe((new \Middlewares\BasicAuthentication([
                    'username1' => 'password1',
                    'username2' => 'password2'
                    ])
            )->attribute('username')->realm('My realm'));

    //Example using other library
    $app->pipe(new Tuupola\Middleware\HttpBasicAuthentication([
        "users" => [
            "root" => "t00r",
            "user" => "passw0rd"
        ]
    ]));

Both of the above code work as expected. For e.g. prompting for username and password in the browser and allowing user to view the content when correct credentials are sent. Guzzle is causing issues for you.

I hope this helps.

Related