Discussion:
Basic Auth
Jim Giner
2013-08-27 13:37:49 UTC
Permalink
I"m using basic auth for a few of my pages that I want to limit access
to - nothing of a sensitive nature, but simply want to limit access to.
Want to implement a signoff process, but can't figure it out.

From the comments in the manual I take it one can't do this by simply
unsetting the PHP_AUTH_USER and _PW vars. Can someone explain to me why
this doesn't suffice? The signon process expects them to be there, so
when they are not (after the 'unset'), how come my signon process still
detects them and their values?
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Stuart Dallas
2013-08-27 13:46:09 UTC
Permalink
I"m using basic auth for a few of my pages that I want to limit access to - nothing of a sensitive nature, but simply want to limit access to. Want to implement a signoff process, but can't figure it out.
From the comments in the manual I take it one can't do this by simply unsetting the PHP_AUTH_USER and _PW vars. Can someone explain to me why this doesn't suffice? The signon process expects them to be there, so when they are not (after the 'unset'), how come my signon process still detects them and their values?
The global variables you're referring to are just that, global variables; changing them will have no effect on the browser. Basic Auth was not designed to allow users to log out, but you can make it happen with some Javascript.

Have your log out link call a Javascript function which sends an XMLHttpRequest with an invalid username and password. The server will return a 401 which you ignore and then take the user to whatever URL you want them to see after they log off. Not pretty, but it works.

-Stuart
--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Jim Giner
2013-08-27 14:06:31 UTC
Permalink
Post by Stuart Dallas
I"m using basic auth for a few of my pages that I want to limit access to - nothing of a sensitive nature, but simply want to limit access to. Want to implement a signoff process, but can't figure it out.
From the comments in the manual I take it one can't do this by simply unsetting the PHP_AUTH_USER and _PW vars. Can someone explain to me why this doesn't suffice? The signon process expects them to be there, so when they are not (after the 'unset'), how come my signon process still detects them and their values?
The global variables you're referring to are just that, global variables; changing them will have no effect on the browser. Basic Auth was not designed to allow users to log out, but you can make it happen with some Javascript.
Have your log out link call a Javascript function which sends an XMLHttpRequest with an invalid username and password. The server will return a 401 which you ignore and then take the user to whatever URL you want them to see after they log off. Not pretty, but it works.
-Stuart
Thanks for the timely response!

Before I try your suggestion - one question. Since when is a global
variable not changeable? Doesn't the fact that it reflects a modified
value when I do change it tell me it worked? I change the value to
'xxx' and show it having that value, but when the script is called again
the old value appears. Very confusing!
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Stuart Dallas
2013-08-27 14:14:51 UTC
Permalink
Post by Jim Giner
Post by Stuart Dallas
I"m using basic auth for a few of my pages that I want to limit access to - nothing of a sensitive nature, but simply want to limit access to. Want to implement a signoff process, but can't figure it out.
From the comments in the manual I take it one can't do this by simply unsetting the PHP_AUTH_USER and _PW vars. Can someone explain to me why this doesn't suffice? The signon process expects them to be there, so when they are not (after the 'unset'), how come my signon process still detects them and their values?
The global variables you're referring to are just that, global variables; changing them will have no effect on the browser. Basic Auth was not designed to allow users to log out, but you can make it happen with some Javascript.
Have your log out link call a Javascript function which sends an XMLHttpRequest with an invalid username and password. The server will return a 401 which you ignore and then take the user to whatever URL you want them to see after they log off. Not pretty, but it works.
-Stuart
Thanks for the timely response!
Before I try your suggestion - one question. Since when is a global variable not changeable? Doesn't the fact that it reflects a modified value when I do change it tell me it worked? I change the value to 'xxx' and show it having that value, but when the script is called again the old value appears. Very confusing!
I didn't say you couldn't change it, I said doing so will have no effect on the browser.

It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].

If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!

-Stuart

[1] The one exception to this is $_SESSION, but it's important to know how that works. The $_SESSION array is populated when you call session_start(). It's loaded from some form of storage (files by default) and unserialised in to $_SESSION. When the session is closed, either implicitly by the request ending or by a call to one of the methods that explicitly do it, the contents are serialised to the storage system. Once closed, any changes to $_SESSION will not be stored; it becomes just another superglobal (not that it was ever anything else).
--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Jim Giner
2013-08-27 14:18:10 UTC
Permalink
Post by Stuart Dallas
It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].
If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!
-Stuart
Not really - this is the first time I've had something not work as expected.
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Stuart Dallas
2013-08-27 14:39:28 UTC
Permalink
Post by Jim Giner
Post by Stuart Dallas
It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].
If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!
-Stuart
Not really - this is the first time I've had something not work as expected.
That was said with my tongue very much firmly in my cheek, and so is this:

I've been playing with dynamite since I was 4 - hey, it must be a safe, proper thing to do!

Just because nothing has blown up in your face yet doesn't mean it won't, and I'm concerned that you might not actually see how important it is to make sure you're using the tool correctly.

-Stuart
--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Jim Giner
2013-08-27 14:51:13 UTC
Permalink
Post by Stuart Dallas
Post by Jim Giner
Post by Stuart Dallas
It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].
If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!
-Stuart
Not really - this is the first time I've had something not work as expected.
I've been playing with dynamite since I was 4 - hey, it must be a safe, proper thing to do!
Just because nothing has blown up in your face yet doesn't mean it won't, and I'm concerned that you might not actually see how important it is to make sure you're using the tool correctly.
-Stuart
This may very well be the first time with this problem because I haven't
tried anything like this before.

That said - can you give me some pointers on how to do the JS solution?
I'm calling a script that is similar to the one I used to signon. It
sends out something like:

header("WWW-Authenticate: Basic realm=$realm");
header('HTTP/1.0 401 Unauthorized');
echo "<h3>You have entered invalid credentials<br>";
echo "Click <a href='$return_url'> here </a> to return to the
menu.";
exit();

when it doesn't detect the PHP_AUTH_USER or it is an invalid value.

So - to effect a signoff, what does one do? You said to use an invalid
value, but what do I do with that? How do I ignore the 401? Now I'm
getting the signin dialog and I'm stuck.
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Stuart Dallas
2013-08-27 14:55:34 UTC
Permalink
Post by Stuart Dallas
Post by Jim Giner
Post by Stuart Dallas
It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].
If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!
-Stuart
Not really - this is the first time I've had something not work as expected.
I've been playing with dynamite since I was 4 - hey, it must be a safe, proper thing to do!
Just because nothing has blown up in your face yet doesn't mean it won't, and I'm concerned that you might not actually see how important it is to make sure you're using the tool correctly.
-Stuart
This may very well be the first time with this problem because I haven't tried anything like this before.
header("WWW-Authenticate: Basic realm=$realm");
header('HTTP/1.0 401 Unauthorized');
echo "<h3>You have entered invalid credentials<br>";
echo "Click <a href='$return_url'> here </a> to return to the menu.";
exit();
when it doesn't detect the PHP_AUTH_USER or it is an invalid value.
So - to effect a signoff, what does one do? You said to use an invalid value, but what do I do with that? How do I ignore the 401? Now I'm getting the signin dialog and I'm stuck.
You don't need to do anything on the server-side. You simply need a JS function that sends a request to a URL that requires basic auth, with an Authenticate header that contains an invalid username and password. Then, when your server responds with a 401 Authentication required (which it should already do for an invalid request) you can set location.href to whatever URL you want the logged out user to see.

If you don't know how to make a request from Javascript -- commonly known as an AJAX request -- then google for it. I'd recommend the jquery library if you want a very easy way to do it.

-Stuart
--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Jim Giner
2013-08-27 14:59:46 UTC
Permalink
Post by Stuart Dallas
Post by Stuart Dallas
Post by Jim Giner
Post by Stuart Dallas
It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].
If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!
-Stuart
Not really - this is the first time I've had something not work as expected.
I've been playing with dynamite since I was 4 - hey, it must be a safe, proper thing to do!
Just because nothing has blown up in your face yet doesn't mean it won't, and I'm concerned that you might not actually see how important it is to make sure you're using the tool correctly.
-Stuart
This may very well be the first time with this problem because I haven't tried anything like this before.
header("WWW-Authenticate: Basic realm=$realm");
header('HTTP/1.0 401 Unauthorized');
echo "<h3>You have entered invalid credentials<br>";
echo "Click <a href='$return_url'> here </a> to return to the menu.";
exit();
when it doesn't detect the PHP_AUTH_USER or it is an invalid value.
So - to effect a signoff, what does one do? You said to use an invalid value, but what do I do with that? How do I ignore the 401? Now I'm getting the signin dialog and I'm stuck.
You don't need to do anything on the server-side. You simply need a JS function that sends a request to a URL that requires basic auth, with an Authenticate header that contains an invalid username and password. Then, when your server responds with a 401 Authentication required (which it should already do for an invalid request) you can set location.href to whatever URL you want the logged out user to see.
If you don't know how to make a request from Javascript -- commonly known as an AJAX request -- then google for it. I'd recommend the jquery library if you want a very easy way to do it.
-Stuart
I am familiar with an ajax request (xmlhttprequest) and I have a
function ready to call a script to effect this signoff. I just don't
know what to put in that php script I'm calling. From what you just
wrote I'm guessing that my headers as shown previously may be close -
I"m confused about your mention of "contains an invalid username...".
As you can see from my sample I don't include such a thing.
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Stuart Dallas
2013-08-27 15:56:00 UTC
Permalink
Oops, sent this message from the wrong email address, so the list rejected it.
Subject: Re: [PHP] Basic Auth
Date: 27 August 2013 16:36:27 BST
Post by Stuart Dallas
Post by Stuart Dallas
Post by Jim Giner
Post by Stuart Dallas
It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].
If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!
-Stuart
Not really - this is the first time I've had something not work as expected.
I've been playing with dynamite since I was 4 - hey, it must be a safe, proper thing to do!
Just because nothing has blown up in your face yet doesn't mean it won't, and I'm concerned that you might not actually see how important it is to make sure you're using the tool correctly.
-Stuart
This may very well be the first time with this problem because I haven't tried anything like this before.
header("WWW-Authenticate: Basic realm=$realm");
header('HTTP/1.0 401 Unauthorized');
echo "<h3>You have entered invalid credentials<br>";
echo "Click <a href='$return_url'> here </a> to return to the menu.";
exit();
when it doesn't detect the PHP_AUTH_USER or it is an invalid value.
So - to effect a signoff, what does one do? You said to use an invalid value, but what do I do with that? How do I ignore the 401? Now I'm getting the signin dialog and I'm stuck.
You don't need to do anything on the server-side. You simply need a JS function that sends a request to a URL that requires basic auth, with an Authenticate header that contains an invalid username and password. Then, when your server responds with a 401 Authentication required (which it should already do for an invalid request) you can set location.href to whatever URL you want the logged out user to see.
If you don't know how to make a request from Javascript -- commonly known as an AJAX request -- then google for it. I'd recommend the jquery library if you want a very easy way to do it.
-Stuart
I am familiar with an ajax request (xmlhttprequest) and I have a function ready to call a script to effect this signoff. I just don't know what to put in that php script I'm calling. From what you just wrote I'm guessing that my headers as shown previously may be close - I"m confused about your mention of "contains an invalid username...". As you can see from my sample I don't include such a thing.
For the last time: YOU DO NOT NEED TO MAKE ANY CHANGES SERVER-SIDE.
From the Javascript, request any URL that requires authentication - it doesn't matter. When you make the AJAX request, pass an Authentication header that contains an invalid username and password. If you don't know what I mean by that, please google how HTTP Basic Auth works.
-Stuart
--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Jim Giner
2013-08-27 16:28:01 UTC
Permalink
Post by Stuart Dallas
Oops, sent this message from the wrong email address, so the list rejected it.
Subject: Re: [PHP] Basic Auth
Date: 27 August 2013 16:36:27 BST
Post by Stuart Dallas
Post by Stuart Dallas
Post by Jim Giner
Post by Stuart Dallas
It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].
If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!
-Stuart
Not really - this is the first time I've had something not work as expected.
I've been playing with dynamite since I was 4 - hey, it must be a safe, proper thing to do!
Just because nothing has blown up in your face yet doesn't mean it won't, and I'm concerned that you might not actually see how important it is to make sure you're using the tool correctly.
-Stuart
This may very well be the first time with this problem because I haven't tried anything like this before.
header("WWW-Authenticate: Basic realm=$realm");
header('HTTP/1.0 401 Unauthorized');
echo "<h3>You have entered invalid credentials<br>";
echo "Click <a href='$return_url'> here </a> to return to the menu.";
exit();
when it doesn't detect the PHP_AUTH_USER or it is an invalid value.
So - to effect a signoff, what does one do? You said to use an invalid value, but what do I do with that? How do I ignore the 401? Now I'm getting the signin dialog and I'm stuck.
You don't need to do anything on the server-side. You simply need a JS function that sends a request to a URL that requires basic auth, with an Authenticate header that contains an invalid username and password. Then, when your server responds with a 401 Authentication required (which it should already do for an invalid request) you can set location.href to whatever URL you want the logged out user to see.
If you don't know how to make a request from Javascript -- commonly known as an AJAX request -- then google for it. I'd recommend the jquery library if you want a very easy way to do it.
-Stuart
I am familiar with an ajax request (xmlhttprequest) and I have a function ready to call a script to effect this signoff. I just don't know what to put in that php script I'm calling. From what you just wrote I'm guessing that my headers as shown previously may be close - I"m confused about your mention of "contains an invalid username...". As you can see from my sample I don't include such a thing.
For the last time: YOU DO NOT NEED TO MAKE ANY CHANGES SERVER-SIDE.
From the Javascript, request any URL that requires authentication - it doesn't matter. When you make the AJAX request, pass an Authentication header that contains an invalid username and password. If you don't know what I mean by that, please google how HTTP Basic Auth works.
-Stuart
--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/
It's not the basic auth that I'm having the issue with - it's the
'header' thing and understanding what a 401 is doing and how I'm to
ignore it. Never had to play with these things before and this part is
all new. Let's face it - I'm an applications guy, not a systems guy.
All this talk of headers and such is greek to me.

I have spent the last hour googling away on this topic - still no
understanding.
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Stuart Dallas
2013-08-27 16:53:41 UTC
Permalink
Post by Stuart Dallas
Oops, sent this message from the wrong email address, so the list rejected it.
Subject: Re: [PHP] Basic Auth
Date: 27 August 2013 16:36:27 BST
Post by Stuart Dallas
Post by Stuart Dallas
Post by Jim Giner
Post by Stuart Dallas
It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].
If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!
-Stuart
Not really - this is the first time I've had something not work as expected.
I've been playing with dynamite since I was 4 - hey, it must be a safe, proper thing to do!
Just because nothing has blown up in your face yet doesn't mean it won't, and I'm concerned that you might not actually see how important it is to make sure you're using the tool correctly.
-Stuart
This may very well be the first time with this problem because I haven't tried anything like this before.
header("WWW-Authenticate: Basic realm=$realm");
header('HTTP/1.0 401 Unauthorized');
echo "<h3>You have entered invalid credentials<br>";
echo "Click <a href='$return_url'> here </a> to return to the menu.";
exit();
when it doesn't detect the PHP_AUTH_USER or it is an invalid value.
So - to effect a signoff, what does one do? You said to use an invalid value, but what do I do with that? How do I ignore the 401? Now I'm getting the signin dialog and I'm stuck.
You don't need to do anything on the server-side. You simply need a JS function that sends a request to a URL that requires basic auth, with an Authenticate header that contains an invalid username and password. Then, when your server responds with a 401 Authentication required (which it should already do for an invalid request) you can set location.href to whatever URL you want the logged out user to see.
If you don't know how to make a request from Javascript -- commonly known as an AJAX request -- then google for it. I'd recommend the jquery library if you want a very easy way to do it.
-Stuart
I am familiar with an ajax request (xmlhttprequest) and I have a function ready to call a script to effect this signoff. I just don't know what to put in that php script I'm calling. From what you just wrote I'm guessing that my headers as shown previously may be close - I"m confused about your mention of "contains an invalid username...". As you can see from my sample I don't include such a thing.
For the last time: YOU DO NOT NEED TO MAKE ANY CHANGES SERVER-SIDE.
From the Javascript, request any URL that requires authentication - it doesn't matter. When you make the AJAX request, pass an Authentication header that contains an invalid username and password. If you don't know what I mean by that, please google how HTTP Basic Auth works.
-Stuart
It's not the basic auth that I'm having the issue with - it's the 'header' thing and understanding what a 401 is doing and how I'm to ignore it. Never had to play with these things before and this part is all new. Let's face it - I'm an applications guy, not a systems guy. All this talk of headers and such is greek to me.
HTTP headers are as important for application guys as they are for systems guys. I appreciate that this may be new to you, but it's pretty basic knowledge about how HTTP works.

Basic auth is simple, and you need to understand how it works to understand what I've been trying to say. Here's how HTTP auth works:

1) Browser hits page.
2) The PHP script knows this page requires HTTP Auth, checks the PHP_AUTH_[USER|PW] variables but doesn't find anything, so it responds with an HTTP status of 401 Unauthorised.
3) The browser gets the 401 response and displays the login box.
4) User enters username and password.
5) Browser sends the request again, but this time with an Authorization header containing the username and password. It also caches the username and password for use with future requests.
6) PHP populates the PHP_AUTH_[USER|PW] variables with the username and password in the Authorization header.
7) The PHP script checks those variables as per step 2, finds them, checks they're correct, and then shows the user the page with a 200 OK HTTP response (the default with PHP).
8) Every subsequent request the browser sends to that domain will now include the Authorization header, so the server will never respond with a 401 status again until the browser session ends (i.e. the browser is closed).

So, to log the user out you basically need to override what the browser has cached for the username and password. To do this you need to send a request with a new username and password (technically just a new username). You can do this with a request like http://bogususername:***@www.example.com/ but the 401 response the server returns will cause the browser to display a login box, which is probably not what you want.

So, we do it with Javascript. Send a request using AJAX to any URL that requires authentication, setting our own Authorization header with an invalid username and password. PHP will see that the username and password are incorrect and will respond with a 401 status as per step 2 above, but step 3 will not happen because AJAX requests don't reach the browser's default response handlers (i.e. 401 == display login box).

When our Javascript gets the response it simply redirects the user to a page telling them they've successfully logged out, or whatever you want them to see. The only reason this works is that the browser has now cached the bogus username and password you sent in the AJAX request, so if/when the user then hits another page that requires authentication they will get the login box because those cached details are not valid.

To send the Authorization header with XMLHttpRequest there are username and password parameters to the open method: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest.

Hopefully this makes more sense now.

-Stuart

--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Jim Giner
2013-08-27 17:45:31 UTC
Permalink
Post by Stuart Dallas
Post by Stuart Dallas
Oops, sent this message from the wrong email address, so the list rejected it.
Subject: Re: [PHP] Basic Auth
Date: 27 August 2013 16:36:27 BST
Post by Stuart Dallas
Post by Stuart Dallas
Post by Jim Giner
Post by Stuart Dallas
It's not really confusing so long as you understand how PHP works. Each request is brand new - nothing is retained from previous requests. The two variable you're changing are set by PHP when the request comes in from the browser. The fact you changed them in a previous request is irrelevant because 1) that change was not communicated to the browser in any way, and 2) PHP doesn't retain any data between requests [1].
If you've been coding assuming that changes you make to global variables are retained between requests you must have been having some pretty frustrating times!
-Stuart
Not really - this is the first time I've had something not work as expected.
I've been playing with dynamite since I was 4 - hey, it must be a safe, proper thing to do!
Just because nothing has blown up in your face yet doesn't mean it won't, and I'm concerned that you might not actually see how important it is to make sure you're using the tool correctly.
-Stuart
This may very well be the first time with this problem because I haven't tried anything like this before.
header("WWW-Authenticate: Basic realm=$realm");
header('HTTP/1.0 401 Unauthorized');
echo "<h3>You have entered invalid credentials<br>";
echo "Click <a href='$return_url'> here </a> to return to the menu.";
exit();
when it doesn't detect the PHP_AUTH_USER or it is an invalid value.
So - to effect a signoff, what does one do? You said to use an invalid value, but what do I do with that? How do I ignore the 401? Now I'm getting the signin dialog and I'm stuck.
You don't need to do anything on the server-side. You simply need a JS function that sends a request to a URL that requires basic auth, with an Authenticate header that contains an invalid username and password. Then, when your server responds with a 401 Authentication required (which it should already do for an invalid request) you can set location.href to whatever URL you want the logged out user to see.
If you don't know how to make a request from Javascript -- commonly known as an AJAX request -- then google for it. I'd recommend the jquery library if you want a very easy way to do it.
-Stuart
I am familiar with an ajax request (xmlhttprequest) and I have a function ready to call a script to effect this signoff. I just don't know what to put in that php script I'm calling. From what you just wrote I'm guessing that my headers as shown previously may be close - I"m confused about your mention of "contains an invalid username...". As you can see from my sample I don't include such a thing.
For the last time: YOU DO NOT NEED TO MAKE ANY CHANGES SERVER-SIDE.
From the Javascript, request any URL that requires authentication - it doesn't matter. When you make the AJAX request, pass an Authentication header that contains an invalid username and password. If you don't know what I mean by that, please google how HTTP Basic Auth works.
-Stuart
It's not the basic auth that I'm having the issue with - it's the 'header' thing and understanding what a 401 is doing and how I'm to ignore it. Never had to play with these things before and this part is all new. Let's face it - I'm an applications guy, not a systems guy. All this talk of headers and such is greek to me.
HTTP headers are as important for application guys as they are for systems guys. I appreciate that this may be new to you, but it's pretty basic knowledge about how HTTP works.
1) Browser hits page.
2) The PHP script knows this page requires HTTP Auth, checks the PHP_AUTH_[USER|PW] variables but doesn't find anything, so it responds with an HTTP status of 401 Unauthorised.
3) The browser gets the 401 response and displays the login box.
4) User enters username and password.
5) Browser sends the request again, but this time with an Authorization header containing the username and password. It also caches the username and password for use with future requests.
6) PHP populates the PHP_AUTH_[USER|PW] variables with the username and password in the Authorization header.
7) The PHP script checks those variables as per step 2, finds them, checks they're correct, and then shows the user the page with a 200 OK HTTP response (the default with PHP).
8) Every subsequent request the browser sends to that domain will now include the Authorization header, so the server will never respond with a 401 status again until the browser session ends (i.e. the browser is closed).
So, we do it with Javascript. Send a request using AJAX to any URL that requires authentication, setting our own Authorization header with an invalid username and password. PHP will see that the username and password are incorrect and will respond with a 401 status as per step 2 above, but step 3 will not happen because AJAX requests don't reach the browser's default response handlers (i.e. 401 == display login box).
When our Javascript gets the response it simply redirects the user to a page telling them they've successfully logged out, or whatever you want them to see. The only reason this works is that the browser has now cached the bogus username and password you sent in the AJAX request, so if/when the user then hits another page that requires authentication they will get the login box because those cached details are not valid.
To send the Authorization header with XMLHttpRequest there are username and password parameters to the open method: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest.
Hopefully this makes more sense now.
-Stuart
--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/
Eureka!!!

Thanks to your wonderful explanation - much of which I kinda knew, just
not in such detail - I have a working solution which I will show. From
your latest missive I gleaned that I needed to have a script on my
server that had the authenticate header included as well as my xml js
function opening the connection with a user and pswd value (bogus as
they were).

For those reading along:

My php script that is called from JS via xml/ajax:
<?
//
// BasicAuth_Signoff.php
// A script used by an xml request to enforce a basic auth signoff
//
header("WWW-Authenticate: Basic realm=My Bowling League Data");
header('HTTP/1.0 401 Unauthorized');
echo "true";
exit();
Note: the realm has to match the one used when the user signed in!

My JS xml call:
var myreq = new XMLHttpRequest();
url="http://jimginer.net/bowling_dir/BasicAuth_Signoff.php";
urlmeth = "GET";
myreq.open(urlmeth, url, true,"x","x");
(just the essentials of making the call here)

In my mind I see it like this:
The php script expects authentication to occur because of the first
header, and responds with the 401 because of the 2nd. The JS code calls
the php script and provides the responses to the authentication request
in the open statement.

Any ideas on improving this would be appreciated, but as it stands
above, it's working almost exactly as I wish. The only drawback right
now is that the user only has to hit enter to the first request for a
following signin and he is prompted with a second signin dialog showing
the last valid credentials, making the signoff not that effective.
(Note: both the userid and pswd parms MUST be provided in the XML open
call or IE defaults the next attempt to signon to the last working set
of credentials, making the signoff even more fruitless.) Any tips on
this will also be appreciated.
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Stuart Dallas
2013-08-28 15:02:06 UTC
Permalink
From your latest missive I gleaned that I needed to have a script on my server
One last time: YOU DON'T NEED TO CHANGE ANYTHING ON THE SERVER-SIDE!

Ok, I see that you've decided to use another method, which is great; HTTP auth is a pretty antiquated way to handle authentication these days. Whatever you're using, I wish you all the best with it.

-Stuart
--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/
Jim Giner
2013-08-28 13:30:43 UTC
Permalink
Stuart,

Just wanted to follow up with my thanks for your excellent help in
providing understanding of how to generate the 401 error page and
getting me thru the process of performing a sign-out from basic auth.
Without your patience it never would have happened.

Also wanted to tell you that I've scrapped it all. Keeping the code for
a rainy day of course, but giving up on using it (as well as the basic
auth signon process) to use my own 'roll-your-own' code. Since IE
insisted on presenting multiple credentials during the signon process it
was a futile effort to be doing a signoff. And yes - I've taken the
proper precautions to hash the incoming password value before submission
and storing in my db that way.

Thanks again. It's help like this that makes this group such a great
resource.
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
B. Aerts
2013-08-27 16:34:27 UTC
Permalink
Post by Jim Giner
I"m using basic auth for a few of my pages that I want to limit access
to - nothing of a sensitive nature, but simply want to limit access to.
Want to implement a signoff process, but can't figure it out.
From the comments in the manual I take it one can't do this by simply
unsetting the PHP_AUTH_USER and _PW vars. Can someone explain to me why
this doesn't suffice? The signon process expects them to be there, so
when they are not (after the 'unset'), how come my signon process still
detects them and their values?
Hello Jim,

at the risk of under-estimating your knowledge (and over-estimating
mine) of HTTP-requests in PHP - but here it goes.

I see two options of bypassing the JavaScript option.

The first one is to use the default authorization, and error pages of
your HTTP server.
(For example, in Apache:
http://httpd.apache.org/docs/2.2/custom-error.html)
This is for a login with invalid credentials.
For some-one to leave the protected site, a HTTP-request without
credentials, and to a URI outside the protected domain, should do (as
every HTTP request into the protected domain should repeat the
Authorisation header).


The second one is to leave header(), and go down one level, to the likes
of fsockopen() or stream_socket_server() - though personally, I've only
limited knowledge of a bit of client-side programming.

Unless I've completely misunderstood your question,
Hope this helps,

Bert
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Loading...