Search code examples
javascriptnginxbasic-authenticationsolid-js

Basic authentication with nginx does not work when transitioning pages on a static site created with SolidJS


If I directly access a page that restricts access by Basic Authentication, the Basic Authentication dialog is displayed, but if I transition from another page that does not restrict access, the Basic Authentication dialog is not displayed and I am able to access the page.

The static site was created as follows:

$ npm init solid@latest
$ cd project-directory
$ npm install
$ vim app.config.js
$ npm run build
$ rm -rf /usr/share/nginx/html && mkdir /usr/share/nginx/html
$ cp -r .output/public/. /usr/share/nginx/html/

The contents of app.config.js are as follows:

import { defineConfig } from "@solidjs/start/config";

export default defineConfig({
  server: {
    prerender: {
      crawlLinks: true
    }
  }
});

The contents of /etc/nginx/nginx.conf are as follows:

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    server {
        listen       80;
        server_name  localhost;
        root   /usr/share/nginx/html;
        index  index.html;

        location /about/ {
            auth_basic "Restricted";
            auth_basic_user_file /etc/nginx/.htpasswd;
        }
    }
}

This site was created with SolidJS and hosted by nginx.
This site has a home page and an /about/ page.
The home page has a link to /about/.
When I go directly to http://xx.xx.xx.xx/about/, Basic Authentication works, but when I go to /about/ from the link on the home page, Basic Authentication does not work and I can access without username and password.

My environment is as follows:

  • OS: Ubuntu 24.04 LTS
  • Node.js: 22.4.1
  • nginx: 1.27.0
  • JavaScript packages:
    • @solidjs/meta: 0.29.4
    • @solidjs/router: 0.14.1
    • @solidjs/start: 1.0.5
    • solid-js: 1.8.18
    • vinxi: 0.4.0

How can I restrict all access to /about/ with Basic Authentication?


Solution

  • You say you're using nginx, which leads me to believe you're using static-site-generation (SSG). But if you generate all the files ahead of time and make them available on your web server (e.g. nginx), then if somebody knows the correct URL, they can just download that file. Thus if this needs to be really actually secure, you cannot do it with a static-site generation setup. It would be possible if you would want to hide the whole page behind basic auth, but you say only some pages.

    To protect only certain pages, I see three options:

    • Stick with Solid.js and use SolidStart, but don't prerender all the pages. In that case, you will also need to remove nginx and instead deploy your site to Netlify (or a similar service) that runs your code and checks on each request whether the page is allowed to be sent out (e.g. using basic auth).
    • Use an MPA (multi-page app) architecture instead of SPA. That way each navigation causes a new page load and you can do the basic auth server-side, even though it's statically generated (that's e.g. how Astro works).
    • Finally, if you're fine with it being not so secure, you can keep the SPA and just display some kind of dialog client-side instead of using basic auth.

    P.S. Confused about SSG vs. SSR and SPA vs. MPA? Have a look at my blog post.