PDA

View Full Version : HOWTO: Log users into a members area with DA username


FarCry
07-21-2003, 05:59 PM
Problem:
Well, i was faced with a problem of login users into a members area i'm making for spinnahost. We didn't want users to have to register for the members area, as that would put them off using it, we didn't want to skin it into DA, because then we wouldn't know if they had authenticated or not, and we didn't want to use their client exec details.

So, this left us with using their system username and password. Now, we could have authenticated using the shadow file :o but thats a little bit of a security problem, so i thought that i would try out using DirectAdmin to log users in :)

solution
First of all, i worked out what exactly DA needed to have posted to it, "username" and "password", once that was working i had to find out what http headers would be returned on a good login, and a bad... these were (in part) "302 Found" and "401 Unauthorized", fairly standard :)

Now i know that, we have to write up (in php) to request that page, then find out what the http header was, then do something depending on if they were successful or not.

This is the code i came up with, its coded so you could add in more control panels if you needed to :o


<?php
session_start();
// nothing was posted, so display the login form
if (empty($_REQUEST['a'])) { ?>
<form action="<?php
// we are posing this data back to this script
echo $_SERVER['PHP_SELF'];
?>" method="post" name="frmLogin" id="frmLogin">
<table width="100%" border="0" cellspacing="1" cellpadding="3">
<tr>
<td colspan="2"> <div align="center"><strong>Member Login</strong></div></td>
</tr>
<tr>
<td>Domain Name:</td>
<td><input name="domain" type="text" id="domain"></td>
</tr>
<tr>
<td width="25%">Username:</td>
<td> <input name="username" type="text" id="username" maxlength="15"></td>
</tr>
<tr>
<td>Password:</td>
<td> <input name="password" type="password" id="password" maxlength="15"></td>
</tr>
<tr>
<td colspan="2"> <div align="center">Logging in may take a few seconds,
please don't refresh the page.<br>
<input name="cp" type="hidden" value="DA">
<input name="a" type="hidden" id="a" value="login">
<input type="submit" name="Submit" value="Login">
</div></td>
</tr>
</table>
</form>
<?php } else {
// what IP are we loging users into?? important if we have more than 1 server
$ip = gethostbyname($_REQUEST['domain']);

// for multipule CP's you need to be able to switch them, so here it is
switch ($_REQUEST['cp']) {

// we want DA, of course
case 'DA':
// DA's port is 2222 (http://YOURIP:2222)
$port = 2222;

// build up the content to post to DirectAdmin
$content = "username=".$_REQUEST['username']."&password=".$_REQUEST['password'];

// how long is the content we are posting?
$contentlen = strlen($content);

// the http header we are going to send to direct admin, don't mess with this!
$request = "POST /CMD_LOGIN HTTP/1.1\r\nHost: $ip:$port\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: $contentlen\r\n\r\n$content\r\n\r\n";

// what header are we getting if successful?
$yes = "302 Found";

// what header is going to be there if unsuccessful?
$no = "401 Unauthorized";

// now we are done, break this statement
break;
}

// open a connection to DA
$fp = fsockopen($ip, $port, $errno, $errstr, 30);

if (!$fp) {
// something went wrong =( we couldn't open up the connection to DA
echo "ERROR: $errstr ($errno)<br>\n";
} else {
$loggedin=false;

// send DA the http header, and the username/password
fputs ($fp, $request);

// now we can get the response, grab the first line, then loop though the others
// this is the correct way to do things, rather than getting the data in the loop =)
$line = fgets ($fp,1024);
while (!feof($fp)) {
// cool, the information we sent logged in our user! set our loggedin variable to true,
// then break out of the loop (because we dont need anything else)
if (strpos($line, $yes) != false) { $loggedin = true; break 1; }

// damn, the info we sent over failed, lets break the loop because we dont need anything more
if (strpos($line, $no) != false) { break 1; }

// get the next line (not that we should need too)
$line = fgets ($fp,1024);
}

// close the connection to DA
fclose ($fp);

// do stuff depending on if they are logged in or not
if ($loggedin) {
// user is logged in, lets setup some session vars for use in our scripts
$_SESSION['LOGGEDIN'] = true;
$_SESSION['USERNAME'] = $_REQUEST['username'];
$_SESSION['PASSWORD'] = $_REQUEST['password'];
} else {
// use did NOT log in successfully (or something went wrong), you might want a message here
// saying that they did not login correctly
$_SESSION['LOGGEDIN'] = false;
echo "login failed";
}
}
}
?>

loopforever
08-07-2003, 05:31 AM
Very cool idea :) - Thanks for sharing this!

Gadget
08-24-2003, 12:03 AM
ok im kind of new to this (php) what would i do to give the user a customized billing center page based on their account and login info (including like billing information and current overages from the server) i looked all through this above example and found no links to other "member pages" :\ can you please help with this as this is exactly what i was looking for when i came to the board tonight !

FarCry
08-24-2003, 12:38 AM
well, your going to want to know some php before you try anything like that...

ProWebUK
08-24-2003, 03:01 PM
echo "login failed"

shouldnt that be:

echo "login failed";

:D

FarCry
08-24-2003, 06:44 PM
true true, the idea is that they will replace that code with their own :)

ProWebUK
08-24-2003, 07:11 PM
also you have session variables but you dont start a session :p

razorblue
11-22-2003, 03:27 PM
Has anyone got any idea how I can leave the DA session open so that when the user logs into this members area they can just click a link and go into the DA panel (ie don't close the connection)

Dan

FarCry
11-22-2003, 03:39 PM
Sorry, but this just verifies a users data, it does not in create a session with DA that can be used afterwards.

I will re-write this as there are new API functions available to do just this.

razorblue
11-22-2003, 03:55 PM
Is there any way you can store the username/pass values when they first login so that you can have a link in your own client control panel that says login to da - and posts the values to da login?

ProWebUK
11-22-2003, 04:06 PM
It cant get simpler, just post the 'username' and 'password' variables to http://YOURIP:2222/CMD_LOGIN

example:

http://prowebuk.com/TEMP/dalogin.php

razorblue
11-22-2003, 04:09 PM
so the variables allready exist yes?

so all i need is a login button and a form and thats it?

ProWebUK
11-22-2003, 04:21 PM
Originally posted by razorblue
so the variables allready exist yes?

so all i need is a login button and a form and thats it?

view the source of my example :)

razorblue
11-22-2003, 04:23 PM
thanks,

I take it I can use hidden fields?

ProWebUK
11-22-2003, 04:25 PM
certainly :)

razorblue
11-22-2003, 04:29 PM
Hmm - its not working code for both files posted below - please can you sort if out for me :D - sorry but im a bit thick when it comes to coding.

<?php
session_start();
// nothing was posted, so display the login form
if (empty($_REQUEST['a'])) { ?>
<form action="http://www.razorblue.com/members.php" method="post" name="frmLogin" id="frmLogin">
<table width="100%" border="0" cellspacing="1" cellpadding="3">
<tr>
<td colspan="2"> <div align="center"><strong>Member Login</strong></div></td>
</tr>
<tr>
<td>Domain Name:</td>
<td><input name="domain" type="text" id="domain"></td>
</tr>
<tr>
<td width="25%">Username:</td>
<td> <input name="username" type="text" id="username" maxlength="15"></td>
</tr>
<tr>
<td>Password:</td>
<td> <input name="password" type="password" id="password" maxlength="15"></td>
</tr>
<tr>
<td colspan="2"> <div align="center">Logging in may take a few seconds,
please don't refresh the page.<br>
<input name="cp" type="hidden" value="DA">
<input name="a" type="hidden" id="a" value="login">
<input type="submit" name="Submit" value="Login">
</div></td>
</tr>
</table>
</form>
<?php } else {
// what IP are we loging users into?? important if we have more than 1 server
$ip = gethostbyname($_REQUEST['domain']);

// for multipule CP's you need to be able to switch them, so here it is
switch ($_REQUEST['cp']) {

// we want DA, of course
case 'DA':
// DA's port is 2222 (<a href="http://YOURIP:2222" target="_blank">http://YOURIP:2222</a>)
$port = 2222;

// build up the content to post to DirectAdmin
$content = "username=".$_REQUEST['username']."&password=".$_REQUEST['password'];

// how long is the content we are posting?
$contentlen = strlen($content);

// the http header we are going to send to direct admin, don't mess with this!
$request = "POST /CMD_LOGIN HTTP/1.1\r\nHost: $ip:$port\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: $contentlen\r\n\r\n$content\r\n\r\n";

// what header are we getting if successful?
$yes = "302 Found";

// what header is going to be there if unsuccessful?
$no = "401 Unauthorized";

// now we are done, break this statement
break;
}

// open a connection to DA
$fp = fsockopen($ip, $port, $errno, $errstr, 30);

if (!$fp) {
// something went wrong =( we couldn't open up the connection to DA
echo "ERROR: $errstr ($errno)<br>\n";
} else {
$loggedin=false;

// send DA the http header, and the username/password
fputs ($fp, $request);

// now we can get the response, grab the first line, then loop though the others
// this is the correct way to do things, rather than getting the data in the loop =)
$line = fgets ($fp,1024);
while (!feof($fp)) {
// cool, the information we sent logged in our user! set our loggedin variable to true,
// then break out of the loop (because we dont need anything else)
if (strpos($line, $yes) != false) { $loggedin = true; break 1; }

// damn, the info we sent over failed, lets break the loop because we dont need anything more
if (strpos($line, $no) != false) { break 1; }

// get the next line (not that we should need too)
$line = fgets ($fp,1024);
}

// close the connection to DA
fclose ($fp);

// do stuff depending on if they are logged in or not
if ($loggedin) {
// user is logged in, lets setup some session vars for use in our scripts
$_SESSION['LOGGEDIN'] = true;
$_SESSION['USERNAME'] = $_REQUEST['username'];
$_SESSION['PASSWORD'] = $_REQUEST['password'];
include 'include.php';

} else {
// use did NOT log in successfully (or something went wrong), you might want a message here
// saying that they did not login correctly
$_SESSION['LOGGEDIN'] = false;
echo "login failed";
}
}
}
?>


Thats the first file - now my include file:

<html>
<body>
<form name="form1" method="post" action="http://razorblue.com:2222/CMD_LOGIN">
<input type="submit" name="Submit" value="Submit">
<input name="username" type="hidden" id="username">
<input name="password" type="hidden" id="password">
</form>
</body>




Thanks,

Dan

FarCry
11-22-2003, 04:47 PM
make your include be:

<html>
<body>
<form name="form1" method="post" action="http://razorblue.com:2222/CMD_LOGIN">
<input type="submit" name="Submit" value="Submit">
<input name="username" type="hidden" value="<?php echo $_SESSION['USERNAME']; ?>">
<input name="password" type="hidden" value="<?php echo $_SESSION['PASSWORD']; ?>">
</form>
</body>

razorblue
11-22-2003, 04:48 PM
ah ha - thanks :D

FarCry
11-22-2003, 04:58 PM
no probs

razorblue
11-22-2003, 05:01 PM
another quick question:

on my login form - for the domain value - i've got a dropdown box to select from all our different servers - the value of this is obviously the servers ip - is there any way I could use this value in the include (login to da form) so that it logs you into the correct server.

Eg- if user selects server1 with ip 1.1.1.1 - the user is authenticated as normal and then they go to the login button

the include then submits the form to http://1.1.1.1:2222/CMD_LOGIN

so the server ip is included.

razorblue
11-22-2003, 05:04 PM
doesn't matter

done it :D

FarCry
11-22-2003, 05:24 PM
try changing:

if ($loggedin) {
// user is logged in, lets setup some session vars for use in our scripts
$_SESSION['LOGGEDIN'] = true;
$_SESSION['USERNAME'] = $_REQUEST['username'];
$_SESSION['PASSWORD'] = $_REQUEST['password'];
include 'include.php';


TO

if ($loggedin) {
// user is logged in, lets setup some session vars for use in our scripts
$_SESSION['LOGGEDIN'] = true;
$_SESSION['USERNAME'] = $_REQUEST['username'];
$_SESSION['PASSWORD'] = $_REQUEST['password'];
$_SESSION['SERVER'] = $_REQUEST['domain'];
include 'include.php';


then on your form set the action to:
action="http://<?php echo $_SESSION['SERVER']; ?>:2222/CMD_LOGIN"

razorblue
11-22-2003, 05:25 PM
lol - beatcha to it - thanks anyway

razorblue
11-23-2003, 04:18 AM
Now I need some more help

On my site at http://www.razorblue.com/rbsite_final_header/

I've got a login box - using the members script I want to do something like this for the login box:

If logged in
echo - logged in as <username>
else (ie not logged in)
(display the logon box)

can anyone help me with the code for this please :confused:

Thanks,

Dan

FarCry
11-23-2003, 06:00 AM
You might want to change


} else {

// use did NOT log in successfully (or something went wrong), you might want a message here

// saying that they did not login correctly

$_SESSION['LOGGEDIN'] = false;

echo "login failed";

}


TO


} else {
// use did NOT log in successfully (or something went wrong), you might want a message here
// saying that they did not login correctly
$_SESSION['LOGGEDIN'] = false;
include ( 'loginfailed.php');
}


and make a "loginfailed.php" which would contain a failed login message

razorblue
11-23-2003, 07:36 AM
Hi thats not quite what I want to do -

In the members.php file - with the code in it to log into DA i'm doing a header to the index file. Thats that bit.

Now for this bit - if you take a look at the url above you'll see theres a login box in the top corner - I want it to check to see if the user is logged in - if they are - display "logged in as ..."

otherwise (ie if theyre not)

Put the logon fields there - ie username, password, etc to allow the user to log on.

Thanks,

Dan

FarCry
11-23-2003, 10:02 AM
if they are getting to your include.php, then they are logged in.

There is a session variable that holds their username ($_SESSION['USERNAME']) which you can use.

eg:

Welcome back <?php echo $_SESSION['USERNAME']; ?>

razorblue
11-23-2003, 01:33 PM
Hi,

I've got the script working - but what i want to know is how to keep the user logged in if they leave that page by using cookies - i've never used cookies before so could someone show me how to do it in this situation.

Thanks,

Dan

FarCry
11-23-2003, 01:58 PM
how much php do you know/understand?

razorblue
11-23-2003, 02:09 PM
Not a lot really - I fixed the last bit though was missing a ; - please see my edited post above as this is my next problem.

Sorry to be a nuisance,

Dan

FarCry
11-23-2003, 02:10 PM
If i get time i'll re-write the whole thing for you this morning to use the new API funtions, and to integrate with sites a bit better.

razorblue
11-23-2003, 02:20 PM
I've edited it slightly so that it's based into my webpage as the logon box - it works perfectly - i just need it to stay logged in once you're logged in - aparently that can be done with a cookie - so thats all i need for perfection

Thanks.

FarCry
11-23-2003, 02:27 PM
this script is far from perfection, its not even OOP!!!

add as the very first line of you page:
<?php session_start(); ?>

and then you can check if a user is logged in with:

<?php
if ( isset ( $_SESSION['USERNAME'] ) )
{
// TO DO: Logged in
}
else
{
// TO DO: Login Form
}
?>

razorblue
11-23-2003, 02:53 PM
I've put that bit at the top of the page:

Basically what i'm doing is having my static page at http://www.razorblue.com/index.php - include the page, the script and the logon form all in the one page and then im going to use index.php?action=whatever to include the various content files in the page.

Im not quite sure what you been by the below - but i'll have a play with it.

Dan

razorblue
11-23-2003, 03:27 PM
Hi,

Still no luck with the above - can you put it into the script above please so I can see where i need to put everything - it seems to me like some parts need to be taken out but im not sure what.

Thanks

razorblue
11-23-2003, 03:48 PM
Don't matter - i've done it - if anyones interested www.razorblue.com/index.php

Dan

razorblue
11-23-2003, 04:45 PM
any idea how i can close the session via a link? Ie logout?

l0rdphi1
11-23-2003, 05:04 PM
if ( $_REQUEST['page'] == 'logout' ) // or whatever
{
session_write_close();
}
See http://www.php.net/session_write_close

I suppose that will work anyway; not following this thread. :)

razorblue
11-24-2003, 10:18 AM
can't get the damn thing to logout - lol - i cant get it to stay logged in - and now i cant logout lol :D

Two_A_T
01-03-2004, 04:40 AM
Can someone offer an updated version of this script (allowing for any changes in the API) that will:

Once the user is logged in successfully, they are redirected to a specific URL/Page
If the user is not successful with login, it will give them 2 more attempts then block them (by ip?) and redirect to another URL/page
Log unsuccessful attempts to a flat file giving the attempted domain, username and IP.

I'm not a coder or I would give this a stab myself. Any help would be greatly appreciated!

ProWebUK
01-03-2004, 05:04 AM
I might do this later today if is not already been done :D

Two_A_T
01-03-2004, 05:13 AM
Thanks Chris!

I had a feeling you would offer to try. That "phriendly-Mark" guy (formerly Spinna-Mark) that originally made the script doesn't have alot of time for us lowly hosts lately since he got a "real" job. Asked him about it today on MSN and his reply was "ask the members in DA forums" LOL ;)

Let me know when you get it done if you're able to find time today. :)









PS to "phriendly-Mark": Just rattling your chain a little! :D

loopforever
01-03-2004, 01:43 PM
Originally posted by razorblue
any idea how i can close the session via a link? Ie logout?

Send a hidden variable to CMD_LOGIN like this:

<input type=hidden name="LOGOUT_URL" value="http://url/ofwhereto/go/whenwe/sign/out.htm">

ctnchris
01-21-2004, 05:43 AM
Originally posted by l0rdphi1
if ( $_REQUEST['page'] == 'logout' ) // or whatever
{
session_write_close();
}
See http://www.php.net/session_write_close

I suppose that will work anyway; not following this thread. :)
that didnt work, but this did
<? session_start(); $_SESSION = array(); session_destroy(); ?>

l0rdphi1
01-21-2004, 05:56 AM
Cool :)

ProWebUK
01-21-2004, 07:15 AM
You don't really need to use the API for logging members in....... you can simply post the "username" and "password" fields (aswell as logout_url etc if you want to take advantage of them, although they are not required) to http://domain.com:2222/CMD_USER_LOGIN or even any page in the control panel :)

Chris

jdlitson
02-05-2004, 10:14 PM
Hi Mark,
Ive been studying your code and, I am new to PHP.
The thing I don't understand is which line of code do I need to
change or add, to make the login display an actual members page once logged in?

Thanks very much for your time and help -Jason

razorblue
02-06-2004, 02:07 PM
I know this is a bit off topic - but has anyone got any idea how to make it work with cpanel - im allready using it with my da servers and ideally would like it to work with my cpanel boxes too - ive tried and i just get access denied. Just changed the port to 2082.

Any ideas?

ProWebUK
02-06-2004, 04:08 PM
Search for it, cpanel forums will more than likely have it webhostchat.com I think used to have it and a few others... definitely possible.

Chris