Как использовать ошибку apache 403 в качестве метода маршрутизации с помощью htacess - PullRequest
0 голосов
/ 04 мая 2019

У меня есть простое веб-приложение php с такой структурой каталогов

.
├── custom_403.html
├── custom_404.html
├── home
│   └── home.php
├── .htaccess
├── index.php
├── login
│   └── login.php
├── public
│   ├── bootstrap
│   ├── css
│   ├── error_pages
│   ├── fontawesome
│   ├── .htaccess
│   └── js
├── signup
│   └── signup.php
├── test.php

Я создал .htacess файл, который в основном выглядит следующим образом

ErrorDocument 404 /public/error_pages/404.php
ErrorDocument 500 /public/error_pages/500.php
ErrorDocument 403 /index.php

Когда я печатаю что-то вроде http://localhost/login/ это должно дать мне ошибку 403 Forbidden, потому что каталог login существует, но не имеет файла index.php.В соответствии с моим .htacess он должен обслуживать файл index.php по умолчанию. Я использую это преимущество на index.php для загрузки файла по указанному пути из адресной строки с помощью jquery.Я ищу window.location.pathname, чтобы загрузить соответствующий файл по этому пути с помощью функции resolveUrl().

Вот пример

<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>

  <!-- Boostrap 4.3 -->
  <link rel="stylesheet" href="/public/bootstrap/css/bootstrap.css">
  <!-- Fontawesome 5 Free -->
  <link rel="stylesheet" href="/public/fontawesome/css/all.css">
  <link rel="stylesheet" href="/public/css/style.css">
  <script src="/public/js/jquery.js"></script>
  <script src="/public/bootstrap/js/bootstrap.js"></script>
</head>

<body>
  <nav class="navbar navbar-expand-lg r-shadow">
    <a class="navbar-brand" href="#"><img width="50" class="d-inline-block align-top" src="https://seeklogo.com/images/M/marvel-comics-logo-31D9B4C7FB-seeklogo.com.png" alt="" srcset=""></a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse justify-content-end" id="navbarText">
      <ul class="navbar-nav">
        <li class="nav-item active">
          <a class="nav-link" href="home">Home</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="login">Login</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="signup">Sign Up</a>
        </li>
      </ul>
  </nav>
  <div class="root">
    <div class="container mt-3 rounded" style="background-color: rgba(255, 255, 255, 0.1); ">dcfdcf</div>
    <div id="loader">
      <div class="spinner"><i class="fas fa-spinner fa-spin"></i></div>
    </div>
  </div>
</body>
<script>
  function resolveUrl(url) {
    if (url) {
      var path = url.replace(/\//gi, '').trim();
      $(".container").load("/" + path + "/" + path + ".php");
      return path;
    } else {
      $(".container").load("/home/home.php");
      console.log(path)
    }
  }

  function resolveActiveTab(pathName) {
    $(".nav-item").removeClass("active");
    if (pathName) {
      $("li > a[href='" + pathName + "']").parent().addClass("active");
    } else {
      $("li > a").first().parent().addClass("active");
    }
  }

  $(document).ready(function () {
    console.log(window.location.pathname)
    var currentPath = resolveUrl(window.location.pathname);
    resolveActiveTab(currentPath)

    $(document).ajaxStart(function () {
      $("#loader").css({
        "display": "block"
      });
    })
    $(document).ajaxStop(function () {
      $("#loader").css({
        "display": "none"
      });
    })

    $('.nav-link').click(function (e) {
      e.preventDefault();
      var path = $(this).attr("href");

      $(".container").load("/" + path + "/" + path + ".php");
      resolveActiveTab(path)
      window.history.pushState("", "", "/" + path);
    })
  })
</script>

</html>

, это означает, что если обновить страницу с путем, подобным http://localhost/login/, jquery загрузит login.php.

Это работает нормальноза исключением того, что я получаю сообщение об ошибке в журнале apache, которое выглядит следующим образом

AH01276: Невозможно обслуживать каталог / var / www / html / test / login /: нет соответствующего DirectoryIndex (index.php, index.html), index.cgi, index.pl, index.xhtml, index.htm) найден, и сгенерированный сервером индекс каталога запрещен директивой Options

Когда я пытаюсь решить эту проблему, изменяя имена файлов сlogin.php signup.php etc до index.php Я получаю эти файлы обратно, так как они существуют, то есть я не получу ошибку 403.Я пытался запретить доступ к этим конкретным файлам в моем .htaccess, но затем они запрещены для всего, включая функцию jquery .load().У меня вопрос, как сделать то, что я делаю эффективно, без ошибки apache.

1 Ответ

1 голос
/ 04 мая 2019

Ваш .htaccess неправильный, вы используете ErrorDocument 403 для загрузки файла index.php, (ErrorDocument обычно используется для пользовательских страниц ошибок, а не для загрузки обычного ресурса), вы хотите иметь Forbidden при попытке загрузить login/, поскольку в этой папке нет файла index.php, но я подозреваю, что в вашем VirtualHost указан параметр Indexes, эта директива загружает содержимое папки, но не служит 403 ошибка.

Мой VirtualHost для целей тестирования:

<VirtualHost localhost-test:80>
  ServerName localhost-test
  ServerAlias localhost-test
  ErrorLog "logs/localhost-test-error.log"
  TransferLog "logs/localhost-test-access.log"
  DocumentRoot "D:/Web/test"
    <Directory />
      Require all granted
      Options FollowSymLinks Includes ExecCGI
      AllowOverride All
    </Directory>
</VirtualHost>

Если вы удалите Indexes из вашего VirtualHost, вы увидите пользовательскую страницу с ошибкой Forbidden. Вы должны иметь:

ErrorDocument 404 /public/error_pages/404.php
ErrorDocument 500 /public/error_pages/500.php
ErrorDocument 403 /public/error_pages/403.php

Теперь, если вы попытаетесь загрузить папку /login/ без файла index.php внутри, у вас должно быть Forbidden 403 с ошибкой вашей пользовательской страницы, но, используя JQuery, вы можете загрузить файл login.php вместо этого.

Надеюсь, это поможет.

...