4
votes

I'm using basic auth on my dev site (e.g. dev.example.com) and I'm running into an issue where my site is not prompting me for credentials after my initial visit. In other words, if I clear my browser cache the prompt appears and I can log in just fine. The session persists just fine, but after the session expires and I'm automatically logged out, I am not prompted again for my credentials.

This also means if I hit 'cancel' I am never prompted again.

Refreshing does not solve the issue, the only way I am able to view the site after my initial visit is to either use an incognito window everytime, or clear the cache and refresh the page.

The page shows a default a 401 nginx error page, and the response is an actual 401 error.

401 page headers

I've tried moving the auth_basic lines to various parts of my configuration, but that seems to have no effect. I don't have a custom 401 error page so I haven't specified error_page 401, could that be a issue?

I also found this issue, IE, FireFox, Opera, and Safari don't display BASIC auth prompt on successive 401 responses from server

Which stated was solved by setting www-authenticate on the headers, but that's defined for me.

Could this be config related? This is my current config:

server {
    server_name dev.MYSITE.com;

    root /srv/dev/MYSITE/current;
    index index.php index.html index.htm;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_max_temp_file_size 0;
        proxy_pass http://localhost:3010;
        proxy_redirect off;
        proxy_read_timeout 240s;

        # Basic HTTP Auth
        auth_basic "MYSITE Dev Site";
        auth_basic_user_file /etc/nginx/sites-password/MYSITE.htpasswd;
    }


    error_page 500 502 503 504 /50x.html;
    location = /50x.html {

    }

    location ~ /\.ht {
        deny all;
    }

    listen 443 ssl http2; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/dev.MYSITE.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/dev.MYSITE.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = dev.MYSITE.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name dev.MYSITE.com;

    return 404; # managed by Certbot
}

Note: I am using nginx as a reverse proxy for a Node.js server.

Edit: I'm not sure why this would be relevant, but this is a Progressive Web App (PWA) that supports offline mode. I just noticed that if I bypass the service worker's cache then the prompts appear correctly (bypassed in dev tools -> Application -> Service Worker -> Bypass for network).

Update: It does appear that my service worker IS caching the 401 response and preventing the prompt. Seems I may need have been looking in the wrong place previously.

Response cached by service worker

Update 2: And now this looks like it is a "feature"...
https://bugs.chromium.org/p/chromium/issues/detail?id=623464

1

1 Answers

1
votes

I would suggest processing the response.status value. If it is not 200 (response.ok) then you probably don't want to cache it.

I recommend running responses through some sort of if/else or switch/case logic for scenarios like handling different response status code, content types, routes, etc.

Service worker caching gets complicated the more complex your application is :)