954,116 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

html/php form for .htaccess validation

Until Microsoft released their security update to IE, I used an html form for the user to input his/her username/password which was passed to ‘username: [email]password@www.domain.com[/email]/restricted_directory’.
The IE patch now restricts this.

When AuthUserFile is in my .htaccess file and I try to access a restricted file, the browser brings up a login popup and I can gain access.

My goal is to login through my html form. I’m very close to getting this working, but I don’t understand how the $auth = false or true get’s passed.

Could it be the <LIMIT GET POST PUT> require valid-user</LIMIT> in the .htaccess needs to change?
Or is something else missing from my .htaccess file?
Do I need something like auth($_SESSION[‘user’], $_SESSION[‘pass’]) in the .htaccess file?

I hope this thread helps other people with this problem. I’ve Googled the heck out of this issue and there are no good examples…
I’ve added my auth.php and .htaccess files below.
I feel that I’m so close, but can’t get passed the finish line.

Also, my DB is Apache.


My auth.php file looks like this ….

[php]<?php
session_start();
$PHP_AUTH_USER = $_POST['username'];
$PHP_AUTH_PW = $_POST['password'];
if (!isset($PHP_AUTH_USER)) $PHP_AUTH_USER = $_COOKIE['username'];
if (!isset($PHP_AUTH_PW)) $PHP_AUTH_PW = $_COOKIE['password'];

$auth = false; // Assume user is not authenticated

if (isset( $PHP_AUTH_USER ) && isset($PHP_AUTH_PW)) {

// Read the entire file into the variable $file_contents

$filename = '/usr/local/zeus/web_roots/main/domain.com/cgi-bin/pa/passwordfile.txt';
$fp = fopen( $filename, 'r' );
$file_contents = fread( $fp, filesize( $filename ) );
fclose( $fp );

// Place the individual lines from the file contents into an array.

$lines = explode ( "\n", $file_contents );

// Split each of the lines into a username and a password pair
// and attempt to match them to $PHP_AUTH_USER and $PHP_AUTH_PW.

foreach ( $lines as $line ) {

list( $username, $password ) = explode( ':', $line );

if ( $username == "$PHP_AUTH_USER" ) {

// Get the salt from $password. It is always the first
// two characters of a DES-encrypted string.

$salt = substr( $password , 0 , 2 );

// Encrypt $PHP_AUTH_PW based on $salt

$enc_pw = crypt( $PHP_AUTH_PW, $salt );

if ( $password == "$enc_pw" ) {

// A match is found, meaning the user is authenticated.
// Stop the search.

$auth = true;
setcookie('username',$PHP_AUTH_USER,time()+360
00);
setcookie('password',$PHP_AUTH_PW,time()+36000
);
break;

}

}
}

}

if ( ! $auth ) {

header( 'WWW-Authenticate: Basic realm="Private"' );
header( 'HTTP/1.0 401 Unauthorized' );
echo 'Authorization Required.';
exit;

} else {

header( 'Location:first.htm' );
}

?> [/php]
My .htaccess file looks like this….

AuthType Basic 
AuthName "Making Doors Open" 
AuthGroupFile /dev/null/ 

php_value auto_prepend_file "/usr/local/zeus/web_roots/main/domainname.com/auth.php" 

<LIMIT GET POST PUT> 
require valid-user 
</LIMIT>
Boat_2005
Newbie Poster
7 posts since Mar 2005
Reputation Points: 10
Solved Threads: 0
 

Can anyone help?

Boat_2005
Newbie Poster
7 posts since Mar 2005
Reputation Points: 10
Solved Threads: 0
 

I'm currently working on the same problem.. I'll let you know if I have any luck with it!

Tarik

Can anyone help?
tarik
Newbie Poster
2 posts since Mar 2005
Reputation Points: 10
Solved Threads: 0
 

That’s great! I hope this thread helps you. I believe that the code I added to this thread is 90% complete. If you figure out the rest that would be incredible..

I'm currently working on the same problem.. I'll let you know if I have any luck with it!

Tarik

Boat_2005
Newbie Poster
7 posts since Mar 2005
Reputation Points: 10
Solved Threads: 0
 

This link may help.
http://www.php.net/manual/en/features.http-auth.php

I'm currently working on the same problem.. I'll let you know if I have any luck with it!

Tarik

Boat_2005
Newbie Poster
7 posts since Mar 2005
Reputation Points: 10
Solved Threads: 0
 

I've had a look through your code and perhaps I am overlooking something but i am slightly confused exactly what you are trying to achieve...

You mention that you used to login using username:password@domain.com, using htaccess authentication and you say that your goal is to login through your html form. From this I would presume that you wanted to continue using the basic httaccess authentication, whilst logging in through the form rather that the popup window (which is what I am attempting myself).

Your code suggests that you are not using htaccess authentication any more - you are writing your own authentication which checks against a custom database file, which is fine, but I don't understand why you need to specify AuthType Basic, or anything within the section in the htaccess file as it is no longer needed.

Rather than needing something like auth($_SESSION[‘user’], $_SESSION[‘pass’]) in the .htaccess file, it looks to me like all you need is to save auth=true in your Session...

e.g, when you establish that the username / password combination is valid then do this...

$_SESSION['auth'] = true;

This variable will now be accessible to you as you navigate around the site.

Whenever a new page is loaded, test whether the user is authenticated by using...

if ( $_SESSION['username'] == true )
{ //Display HTML Content }

Is this what you are trying to achieve?

Tarik

tarik
Newbie Poster
2 posts since Mar 2005
Reputation Points: 10
Solved Threads: 0
 

Removing AuthTypeBasic and from my .htaccess file makes sense.

I can replace $auth = true; with $_SESSION['auth'] = true; and $auth = false; with $_SESSION[‘auth’] = false;.

Do you think that I still need
setcookie('username',$PHP_AUTH_USER,time()+36000);
setcookie('password',$PHP_AUTH_PW,time()+36000);

The part I’m having trouble understanding is how to bridge the gap from my auth.php file to having access.
My HTML forms action point to a file in my restricted directory. When it tries to access that file the .htaccess file directs the username and password to the auth.php file which validates against my username/password file. If it’s valid => “$_SESSION[‘auth’] = true;.

Were would I add this?
if ( $_SESSION['username'] == true )
{ www.domain.com/path/to/restricted/field.html }

I added it to my .htaccess file and when I logged in got the following error => Error 405 Method Not Allowed.

Any ideas? You mentioned that your trying to get this working. Have you been able to? If not what road blocks have you run into?

Boat_2005
Newbie Poster
7 posts since Mar 2005
Reputation Points: 10
Solved Threads: 0
 

I ma having the same problem. Did u come up with a solution ???

I read that its impossible to do this.
I have a bunch of cgi scripts with .htacess. I need to
give access to these scripts only to users who logged in with
same usr/pswd as that in htpasswd file.

psk79
Newbie Poster
2 posts since Apr 2005
Reputation Points: 10
Solved Threads: 0
 
I ma having the same problem. Did u come up with a solution ??? I read that its impossible to do this. I have a bunch of cgi scripts with .htacess. I need to give access to these scripts only to users who logged in with same usr/pswd as that in htpasswd file.




I was wondering if anyone had a solution to this problem. I am in desperate need of code to create a log-in form with a .htaccess file.


I would very much appreciate any help.


Thanks,

DW5

DW5
Newbie Poster
1 post since Oct 2006
Reputation Points: 10
Solved Threads: 0
 

Is the problem how to get let .htaccess know that the user is authorized and set this in php?

I've never used .htaccess for authentication before so I wouldnt know but I can suggest that you remove .htaccess altogether, and use just php if you are deperate. You can still do the exact same thing, read the user and pass from the password file, but have authentication rely on php alone. .. if you're desperate...

digital-ether
Nearly a Posting Virtuoso
Moderator
1,293 posts since Sep 2005
Reputation Points: 461
Solved Threads: 101
 

Is the problem how to get let .htaccess know that the user is authorized and set this in php?

I've never used .htaccess for authentication before so I wouldnt know but I can suggest that you remove .htaccess altogether, and use just php if you are deperate. You can still do the exact same thing, read the user and pass from the password file, but have authentication rely on php alone. .. if you're desperate...

See the issue I am having is this. I have used php / mySQL login authentication to secure all of the php pages in the members area of a site. The problem I have is what if there are html files or pdf files in the members folder that I dont want people to have access to?

For example, my members folder is /public_html/members/ and I have a documents folder in there where I store pdf files for members only at /public_html/members/documents/. If I only use php for authentication (ie user/pass from mysql database) then someone can browse directly to one of the pdf files and view it without a password (ie www.domainname.com/members/documents/file1.php) . The only way I know of to prevent this is with htaccess file. I need to maintain the php login which integrates with the mySQL table since the members area is customized per member?

Can anyone give me an idea as to what I need to do???

Thank you.

Keith G

justhost
Newbie Poster
1 post since Mar 2007
Reputation Points: 10
Solved Threads: 0
 

See the issue I am having is this. I have used php / mySQL login authentication to secure all of the php pages in the members area of a site. The problem I have is what if there are html files or pdf files in the members folder that I dont want people to have access to?

For example, my members folder is /public_html/members/ and I have a documents folder in there where I store pdf files for members only at /public_html/members/documents/. If I only use php for authentication (ie user/pass from mysql database) then someone can browse directly to one of the pdf files and view it without a password (ie www.domainname.com/members/documents/file1.php) . The only way I know of to prevent this is with htaccess file. I need to maintain the php login which integrates with the mySQL table since the members area is customized per member?

Can anyone give me an idea as to what I need to do???

Thank you.

Keith G

Hi Keith;

.htaccess does make it a bit complex. It would be simpler if you just place all the member files under the web root. (below public_html in this case).
This way it cannot be accessed directly from the web.

Then you can have a single php file that:

1) authenticates the users session.
2) retrieves the requested file from below the web root.
3) appends the correct Content-Type HTTP Header for file download or the file type being requested.
4) Dump the file to HTTP (echo $filecontents) so the browser will download the file.

This method can even allow resuming of file downloads etc.

It does put an extra load on the PHP server as file contents have to be read to php before being sent to HTTP...

You can get example code in the PHP manual under the funciton: header http://www.php.net/header

Heres an example:

[php]
<?php
$mm_type="application/octet-stream";

header("Cache-Control: public, must-revalidate");
header("Pragma: hack");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($url)) );
header('Content-Disposition: attachment; filename="'.basename($url).'"');
header("Content-Transfer-Encoding: binary\n");

$fp = fopen($url, 'rb');
$buffer = fread($fp, filesize($url));
fclose ($fp);

print $buffer;
?>
[/php]

You can insert this into a page, after you have validated:
1) The user has a session (is logged in)
2) The file exists and user has access to download it. (very important)

digital-ether
Nearly a Posting Virtuoso
Moderator
1,293 posts since Sep 2005
Reputation Points: 461
Solved Threads: 101
 

I am also having a problem very similar, i want to create a login excatly like the way .htaccess works but without the Annoying Dialogue Pop-up(i hate them) .. Can anyone help me?

harrow124
Newbie Poster
1 post since Apr 2007
Reputation Points: 10
Solved Threads: 0
 
I am also having a problem very similar, i want to create a login excatly like the way .htaccess works but without the Annoying Dialogue Pop-up(i hate them) .. Can anyone help me?

I am coping with the same problem. Anyone know a solution? Maybe including login information in the URL sent from my VB6 browser. Then avoid the pesky "confirm" message box?

Thanks,
Kirk

calvinmicklefin
Newbie Poster
7 posts since Apr 2007
Reputation Points: 10
Solved Threads: 0
 
Until Microsoft released their security update to IE, I used an html form for the user to input his/her username/password which was passed to ‘username: [email]password@www.domain.com[/email]/restricted_directory’. The IE patch now restricts this. ...

Here's a solution to getting around the IE problem with their disabling using the browser address bar to login via HTTP Basic Authentication.

[HTML]Enter A Username and Password to Access the Private Area
[/HTML]

What is does is circumvent the browser address bar by making a xmlHTTPRequest call to a page protected by Basic Auth.

The xmlHTTPRequest will pass the username and password of the user to this page, and if authenticated successfully the page will respond with a HTTP status of "200".
If the authentication fails then the response will be "401".
The xmlHTTPRequest reads the HTTP status responses and keeps asking for a username and password until it gets a "200" response from the page.

Once authenticated, the browser will cache the username and password. (This is done automatically by browsers when implementing Basic Auth) This allows you to redirect to the actual page the user wants to visit.

This works no matter who you implement Basic Auth on the server, via php, via .htaccess etc.

The only problem I have seen is that Firefox will open the default Prompt for Authentication if the authentication by xmlHTTPRequest fails. This does not happen with IE. This may not be a firefox bug, just their implementation.

The work around for this would be to implement HTTP Authentication with PHP and response with a HTTP Response status of "403" or something similar instead of "401" which triggers the login prompt/box in firefox.

digital-ether
Nearly a Posting Virtuoso
Moderator
1,293 posts since Sep 2005
Reputation Points: 461
Solved Threads: 101
 

Could you explain if this script can also be used to make a webbased .htaccess login to directories where the username is the protected directory to which the user is pointed at login?

Eg. username = apple
with pasword will go to host.com/apple (where apple is a .htaccess protected directory).

If so, could you explain what to do with:

// url of Basic Authentication page
var auth_url = '.....';
// url user wants to access
var private_url = '.....';

And give some hints about ho to install the script. Thanks a lot in advance!

SimonJJ
Newbie Poster
3 posts since May 2007
Reputation Points: 10
Solved Threads: 0
 

Could you explain if this script can also be used to make a webbased .htaccess login to directories where the username is the protected directory to which the user is pointed at login?

Eg. username = apple with pasword will go to host.com/apple (where apple is a .htaccess protected directory).

If so, could you explain what to do with:

// url of Basic Authentication page var auth_url = '.....'; // url user wants to access var private_url = '.....';

And give some hints about ho to install the script. Thanks a lot in advance!

This is all you need to change:
[HTML]
// url of Basic Authentication page
var auth_url = '.....';
// url user wants to access
var private_url = '.....';[/HTML]

auth_url can be either a PHP implementation of BASIC Auth ( http://php.net/features.http-auth) . Or an actual protected page.

private_url is the page you want to redirect to when the user is logged in successfully. (a private page).

If you don't have a PHP script implementing BASIC Auth, then both URLs are the same...

In your case it would be:

[HTML]
// url of Basic Authentication page
var auth_url = 'http://host.com/apple';
// url user wants to access
var private_url = 'http://host.com/apple';[/HTML]

You just place the whole script (JS code and HTML form) inside a non-protected page on the same Domain.

Different Domains:
If you want to go past the same domain restriction in XMLHTTPRequest then you'll have to use a PHP HTTP proxy. The PHP proxy should just take the HTTP Request and mirror the same request to the remote domain, then receive the HTTP Response from the remote domain and mirror it back to the client..

digital-ether
Nearly a Posting Virtuoso
Moderator
1,293 posts since Sep 2005
Reputation Points: 461
Solved Threads: 101
 

Thanks a lot for that!

But what to do when the private_url directory is not clear yet (because it is based on what the user will type in the form as it's username).

Can the directory name be a variable based on what the user inputs in the form as it's username?

SimonJJ
Newbie Poster
3 posts since May 2007
Reputation Points: 10
Solved Threads: 0
 
Thanks a lot for that! But what to do when the private_url directory is not clear yet (because it is based on what the user will type in the form as it's username). Can the directory name be a variable based on what the user inputs in the form as it's username?

Sure.

Here's the first part of the code.

// url of Basic Authentication page
var auth_url = 'protected/index.php';
// url user wants to access
var private_url = 'protected/files/file.zip';

function getPrivatePage() {

var user = document.getElementById('user').value;
var pw = document.getElementById('pw').value;


The function getPrivatePage() is executed when a user clicks on the submit button. (it would actually be better to attach this to the form submit handler).

What you can do is check if the username is set when the user has clicked the button, if it is, then append the username to you your private url.

eg:

// url of Basic Authentication page
var auth_url = 'protected/index.php';
// url user wants to access
var private_url = 'protected/files/file.zip';

function getPrivatePage() {

var user = document.getElementById('user').value;
var pw = document.getElementById('pw').value;

if (user.length < 0) {
private_url = 'http://example.com/'+encodeURIComponent(user)+'/';
}


If you want to support older browsers (IE 5.5 I believe support xmlHTTPRequest but not encodeURIComponent()) then you'll have to first check if "encodeURIComponent()" is supported.

eg:

/**
* the escape() method in Javascript is deprecated
*/
function encode( uri ) {
    if (typeof encodeURIComponent == 'function') {
        return encodeURIComponent(uri);
    } else if (typeof escape == 'function') {
        return escape(uri);
    } else return uri;
}


Then in when you use uri's do:

if (user.length < 0) {
private_url = 'http://example.com/'+encode(user)+'/';
}


for example.

There is also some values passed via HTTP in the xmlHTTPRequest that are not urlencoded. You may want to urlencode them.

digital-ether
Nearly a Posting Virtuoso
Moderator
1,293 posts since Sep 2005
Reputation Points: 461
Solved Threads: 101
 

Since auth_url and private_url are the same in my case, should I include

function getPrivatePage() {

var user = document.getElementById('user').value;
var pw = document.getElementById('pw').value;

if (user.length < 0) {
private_url = 'http://example.com/'+encodeURIComponent(user)+'/';

Also for auth_url?

Furthermore, when I tested the script it seems to make a difference
if I use http://host.com or http://www.host.com .

Is is possible to make both work?

Thanks again in advance!

SimonJJ
Newbie Poster
3 posts since May 2007
Reputation Points: 10
Solved Threads: 0
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You