Тонкая Базовая Аутентификация


Всем доброго дня!

У меня здесь есть рабочий тонкий код с slim-basic-auth, и когда я перехожу в каталог с ограниченным доступом, появляется следующее:

enter image description here

Все работает, но то, что я хотел сделать, это перенаправить его на мою страницу входа в систему вместо отображения всплывающего окна входа. Вот моя страница входа в систему:

enter image description here

Мой тонкий код:

$pdo = new \PDO("mysql:host=localhost;dbname=databasename", "username");
$app->add(new \Slim\Middleware\HttpBasicAuthentication([
    "path" => "/main",
    "realm" => "Protected",
    "authenticator" => new PdoAuthenticator([
        "pdo" => $pdo,
        "table" => "accounts",
        "user" => "accountUsername",
        "hash" => "accountPassword"
    ]),
    "callback" => function ($request, $response, $arguments) use ($app) {
        return $response->withRedirect('/main/contacts');
    }

Когда я пытаюсь войти в систему с помощью всплывающего окна входа, это работает, но я действительно хочу перенаправить его на мою страницу входа вместо этого.

Любая помощь была бы очень признательна.

Author: alexw, 2016-03-23

2 answers

Промежуточное программное обеспечение реализует Аутентификацию базового доступа HTTP. Диалоговое окно аутентификации запускается через заголовок ответа. Поставщик браузера должен решить, как запрашивать учетные данные. Большинство браузеров используют описанное вами всплывающее диалоговое окно входа в систему.

То, что вы пытаетесь сделать, - это немного неортодоксальный способ использования базовой аутентификации HTTP. Однако вы можете отключить диалоговое окно входа в систему, удалив заголовок WWW-Authenticate из ответа. Обратите внимание, что вам нужна как минимум версия 2.0.2 чтобы это сработало.

$app->add(new \Slim\Middleware\HttpBasicAuthentication([
    "path" => ["/main"],
    "authenticator" => new PdoAuthenticator([
        "pdo" => $pdo,
        "table" => "accounts",
        "user" => "accountUsername",
        "hash" => "accountPassword"
    ]),
    "error" => function ($request, $response, $arguments) {
        return $response
            ->withRedirect("/auth/login")
            ->withoutHeader("WWW-Authenticate");
    }
]));

Однако с кодом выше вам все равно придется каким-то образом установить заголовок запроса Authentication: Basic. Один из способов сделать это - использовать AJAX-запрос.

$.ajax({
   url: "http://example.com/auth/login",
   username: $("username").val(),
   password: $("password").val(),
   success: function(result) {
     alert("Authorization header should now be set...");
   }
});
 2
Author: Mika Tuupola, 2016-03-25 03:03:41

На данный момент похоже, что вы пытаетесь использовать не базовый аутентификатор Http, а обычный процесс входа в систему, поэтому вам нужно будет использовать сеансы и тому подобное.

Очень простой пример - добавление этого близко к нижней части вашего стека промежуточного программного обеспечения. (это означает, что он будет выполнен первым, так как он будет находиться в верхней части стека)

$middleware = function (Request $request, Response $response, $next) {

    if (!isset($_SESSION['__user'])) {
        //don't interfere with unmatched routes
        $route = $request->getAttribute('route');
        if ($route && !in_array($route->getName(), ['login'])) {
            return $response->withStatus(403)->withHeader('Location', $this->router->pathFor('login'));
        }
    }

    return $next($request, $response);
};
$app->add($middleware);

Глядя на промежуточное программное обеспечение HttpBasicAuthentication, оно всегда будет отправлять заголовок WWW-Authenticate, делая вашу форму входа бесполезной, так как это вызовет всплывающее окно авторизации.

 2
Author: the-noob, 2016-03-23 10:30:22