title: How to add webform login to an nginx basic auth website?
body: <p>I have a simple nginx static site with basic auth. When someone wants to access the site, they get the browser modal dialog prompting for username/password:</p>
  
  <p>nginx.conf:</p>
  
  <pre><code>server {
    listen 1337;
    server_name _;
    root /app/public;
    location / {
      auth_basic "Protected";
      auth_basic_user_file /app/etc/htpasswd;
    }
  }
  </code></pre>
  
  <p>How can change it so that instead of a dialog I end up with a web form to enter username and password against the same <code>htpasswd</code> file?</p>
  
  <p>I tried adding the following to <code>nginx.conf</code>:</p>
  
  <pre><code># In location / block
  error_page 401 =418 /login/?dest=https://$http_host$request_uri;
  
  # In server block
  location /login/ {
    auth_basic off;
  }
  </code></pre>
  
  <p>Return code <code>418</code> to kill the popup and I like teapots. 
  In <code>/app/public/login/</code> I created <code>index.html</code> that has a simple form:</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;script&gt;
  function authenticate() {
    var login = document.getElementById('username').value;
    var pass = document.getElementById('password').value;
    var xhr = new XMLHttpRequest();
    xhr.withCredentials = true;
    xhr.open("GET", "/", true);
    xhr.setRequestHeader("Authorization", 'Basic ' + btoa(login + ':' + pass));
    xhr.onreadystatechange = function() {
      console.log('xhr ready state: ' + xhr.readyState);
      console.log('xhr status: ' + xhr.status);
      console.log('xhr response: ' + xhr.response);
    };
    xhr.send();
  }
  &lt;/script&gt;
  &lt;form method="get" onsubmit="authenticate(); return false"&gt;
      &lt;input type="text" id="username" autocomplete="username" required/&gt;
      &lt;input type="password" id="password" autocomplete="current-password" required/&gt;
      &lt;input type="submit" value="OK" /&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>I tried an AJAX/XHR to the original destination url to see if it returned a 200 (login successful) or 418 (login fail) but I can't figure out how to set the Authorization header on all subsequent requests or if it's possible. Any help / suggestions appreciated.</p>