php - 使用基本授权作为中间件 PSR-7 PSR-15

标签 php architecture middleware

TD;LR:我试图掌握中间件实现背后的理念。它似乎可以正常工作,但我该如何正确处理响应,以便它向浏览器显示基本授权登录提示?

--

我正在使用:

运行下面的代码:

$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);

返回以下内容:

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] => 
)

看起来 middlewares/response-timemiddlewares/http-authentication 执行得很好。但是,我的印象是 middlewares/http-authentication 会显示这样的实际登录提示:

enter image description here

但事实并非如此。我应该自己实现吗?如果是,我怎样才能正确地做到这一点?

最佳答案

请将领域更改为“我的领域”。

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

GuzzleHttp 请求发生在后端,因此它不会像通常在浏览器中那样工作,例如提示输入用户名和密码。当您在不使用任何浏览器的情况下使用 Guzzle 时,您基本上是在模仿请求。因此,如果您需要提示,则必须在不使用 GuzzleHttp 的情况下实现此逻辑。

您仍然可以按照下面的方式使用 Guzzle 对其进行测试。

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

实现 BasicAuthentication 的最佳方式是在中间件框架内。

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"
        ]
    ]));

以上代码都按预期工作。例如在浏览器中提示输入用户名和密码,并允许用户在发送正确的凭据后查看内容。 Guzzle 给您带来了问题。

希望对您有所帮助。

关于php - 使用基本授权作为中间件 PSR-7 PSR-15,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52948852/

相关文章:

javascript - 使用cloudflare缓存动态页面

php - MYSQL审计程序及触发器

ruby-on-rails - Ruby on rails - Rack 中间件排除 - 可能吗?

c# - 为什么 ASP.NET Core 在中间件管道的末尾返回 404?

c# - 在 ASP .Net Core 中的 ExceptionFilterAttribute 中添加响应 header

php - 从表中的 json 中获取单个项目

c# - 实现 IDisposable 是否与组合聚合相矛盾?

javascript - Web应用架构: Implementing MVC in the browser using a server as a repository of data and templates

types - 根据系统切换数据类型?

javascript - 无法并排显示选择的字段?