Protect a single page by a password

What’s a simple but reliable and secure way to prevent a user from accessing a single page by login/password?

A user will have to enter his login/password each time he wants access a page. Once he leaves a page, the next time he returns he should be asked to provide his credentials again.

I’m thinking of returning the content of the page via json and rendering it after a user has submitted his credentials and if they’re correct.

The credentials of each user are different. Each user can have multiple of them.

GET --> show "Enter your credentials"
<---- json POST
json POST return  ----> "Content of the page read from a partial template"

Is this a solid solution? Is there a better one?

One issue is that the content can contain javascript, buttons, handlers, etc… There can be difficulties to make dynamic javascript content work

You can always just send a simple HTTPAuth header and validate what they send back? The super-simple-ugly-standards way.

I don’t understand. How is a user supposed to send that simple HTTPAuth header when he comes to html Protected Page in a browser?

Standard HTML standards. ^.^

Just in your controller check if the proper "Authorization" header is set first:

  • If it is not set then return a 401 while setting the "WWW-Authenticate", something like WWW-Authenticate: Basic realm="My Website" charset="UTF-8" or so. The user will get a browser popup asking for a username and password or so.
  • If it is set then just compare the value passed in to see if it is authorized or not.

It is the oldest web authentication standard supported everywhere by everything that requires nothing fancy whatsoever, and thus if you just want to protect a single page by a super-simple auth like a password or so, then there really is nothing more simple. :slight_smile:

2 Likes

You can also do it on Reverse Proxy like NGINX.

1 Like

Not really what he wants, as a user is supposed to choose from a set of credentials on each subsequent request to that resource. At least that’s how I understand the initial requirements from the OP.

That’s not really what I gathered from this bit of his though?

I took that bit from here…

Sure, they can type in whatever username/password they need. I don’t see anything about ‘displaying’ though?

I never said something about display.

Only that one subsequent requests to the resource the credentials should be asked for again.

Oh, yes. And then a user would have to use curl to get access to my page and manually set the header.

Actually curl has first-class support for it as it is part of the base spec (just like browsers will automatically popup a username/password box when they get that header). :slight_smile:

curl https://username:password@some.site/blah/a/path

The username:password@ bit is part of the URL/URI spec too, and they set that authentication header in any conformant machinery (such as curl). :slight_smile:

No they don’t. It’s integrated into every browser.

The user flow for this is like that:

  • User visits the page by an URL
  • The webserver responds with a 401 status code + that “WWW-Authenticate” header (instead of a status 200 and the html of a page)
  • The browser shows a dialog to enter a username and a password
  • The user puts in his credentials and clicks OK
  • Browser sends request withe the credentials to webserver
  • The webserver checks the given credentials and returns a 200 status code + the html for your page (if the credentials are correct, otherwise the webserver simply returns that 401 + the header again)

This is a very nice solution for a simple authentication workflow. A more in depth explanation can be found over here HTTP authentication - HTTP | MDN

I think this requirement is not solvable in a nice way with HTTPAuth because some (if not all) browsers cache these credentials and sets the authentication information in each subsequent request for some time. More info on this over here: How do I make Firefox forget HTTP Basic Auth? - Super User

Could you clarify, why a user needs to have different credentials and needs to provide them with every page visit? It sounds like a cumbersome thing for the user :wink:

1 Like

The usual method is to timestamp the Realm and encode it in. :slight_smile: