Logging In To Joomla 1.5 Using External Form (not within joomla folder, but on same server)
Asked Answered
C

3

6

I currently have a Joomla 1.5 installation, as well as another website. They both reside on the same web server. They are in different folders within the wwwroot directory, however. I would like to place a login form within the non-joomla website, which will log the user in to Joomla. I have already tried copying and pasting the Joomla login form code into a page on the non-joomla site, and everything works fine up until the secret form value is not correct. Any help is greatly appreciated.

EDIT: Here is the code-

Contact form:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>

<body>
<form id="login" name="login" method="post" action="login.php">
  <label>
  <input name="username" type="text" id="username" value="username" />
  </label>
    <label>
    <input name="password" type="password" id="password" value="password" />
    </label>
  </p>
  <p>
    <label>
    <input type="submit" name="submit" id="submit" value="Submit" />
    </label>
  </p>
</form>
</body>
</html>

Login Script:

<?php
$uname = $_POST['username'];
$upswd = $_POST['password'];
$url = "http://www.mywebsite.com/joomla_site/index.php";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt($ch, CURLOPT_COOKIEJAR, './cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, './cookie.txt');
curl_setopt($ch, CURLOPT_HEADER, FALSE );
$ret = curl_exec($ch);
if (!preg_match('/name="([a-zA-z0-9]{32})"/', $ret, $spoof)) {
    preg_match("/name='([a-zA-z0-9]{32})'/", $ret, $spoof);
}

// POST fields
$postfields = array();
$postfields['username'] = urlencode($uname);
$postfields['passwd'] = urlencode($upswd);
$postfields['lang'] = '';
$postfields['option'] = 'com_login';
$postfields['task'] = 'login';
$postfields[$spoof[1]] = '1';
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$ret = curl_exec($ch);
?>
Crape answered 3/3, 2011 at 2:52 Comment(0)
S
9

Ok, in order for this to work here is what needs to be done -

  1. Create a new session and get the associated token
  2. Pass the username, password, and token to create a logged in session
  3. Get the new cookie values for logged in session
  4. Transfer cookie to the browser

Here is the code needed to accomplish all of this:

<?php
$uname = $_POST['username'];
$upswd = $_POST['password'];
$url = "http://joomla website.com";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE );
curl_setopt($ch, CURLOPT_COOKIEJAR, realpath('./cookie.txt'));
curl_setopt($ch, CURLOPT_COOKIEFILE, realpath('./cookie.txt'));
curl_setopt($ch, CURLOPT_HEADER, TRUE );
$ret = curl_exec($ch);
if (!preg_match('/name="([a-zA-z0-9]{32})"/', $ret, $spoof)) {
    preg_match("/name='([a-zA-z0-9]{32})'/", $ret, $spoof);
}

// POST fields
$postfields = array();
$postfields['username'] = urlencode($uname);
$postfields['passwd'] = urlencode($upswd);
$postfields['option'] = 'com_user';
$postfields['task'] = 'login';
$postfields[$spoof[1]] = '1';
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$ret = curl_exec($ch);

// Get logged in cookie and pass it to the browser
preg_match('/^Set-Cookie: (.*?);/m', $ret, $m);
$cookie=explode('=',$m[1]);
setcookie($cookie[0], $cookie[1]);
?>

This should work on any Joomla website as long as the URL used in the script has a login form on the page. Once you run this script you should then be able to access the website and be logged in.

Sternick answered 6/3, 2011 at 0:30 Comment(4)
It works perfectly! Thank you so much for all this help, I really appreciate it.Crape
I have one quick follow up question. This script works perfectly on my machine and all of my browsers, but on some machines this script does not log the user in properly. Are there any specific OS or browser settings that could interfere with the operation of this script?Crape
Having cookies turned off will be an issue because this requires the cookie to transfer the session to the browser. Other than that, it should be browser neutral, everything happens server side.Sternick
Nice script but I found you have to get rid of the urlencode() function around the username and password otherwise it would fail if the username or password contain any punctuation characters.Wadleigh
S
1

It's not working because Joomla requires a unique token with each login request. It generates a new token every time it creates a login form and that token is associated with the user session. In order for your login to work, you are going to have to create a new session and pull the associated token to submit with your form. There was a similar question a while back that has some good answers on how to establish the session and get the token.

CURL login by script to a Joomla website

Sternick answered 3/3, 2011 at 4:36 Comment(31)
Thank you for the reply. I visited that page and tried to use the code in the very last answer. Unfortunately I am very new to php as well as Joomla, and I am having trouble getting the code to function properly. What do I need to do or pass on from my form to this code in order for my login form to function properly? At the moment, when I try to load that code alone in my browser, I get a call to undefined function error referencing curl_init(). Once again thank you very much for the help.Crape
I managed to enable CURL on my webserver, so the undefined function error is no longer occurring. I am still having trouble implementing this code properly, however. Do I need to pass information from my form to this code, or from this code to my form, and then to Joomla? Once again thanks.Crape
The script at the bottom of the page is what you would submit your form to. You'd need to pass the username and password from your form to that script. The script then uses cURL to start a session, generator and retrieve the token, then submit the whole mess including your username and password back to Joomla.Sternick
I created a login form with a username field, password, and submit button. This form uses POST to send the data to that script. The username is sent as "id" and the password is sent as "pswd." I have changed the url in the script to the index.php file of my Joomla installation. When I submit my form, the data is sent to the script, but I am not sure if I actually get logged in. After logging in using my form and this script, if I actually go to my Joomla site, it tells me that I am not logged in and must log in.Crape
If you haven't already you will need to change $uname = "id"; to $uname = $_POST['id']; and $upswd = "pswd"; to $upswd = $_POST['pswd'];Sternick
Yes, I have done that. The only other thing that I changed in the script is the url, which I set to the index.php file of my Joomla site (the url, not the internal server location), I am not sure if that is correct. It is not logging me in, however, because after logging in using this form, if I go to my Joomla site I am logged out.Crape
I just edited the original question with my code for the login form as well as the login script.Crape
What do you get when add print_r($postfields);?Sternick
I get this: Array ( [username] => myuser [passwd] => mypass [lang] => [option] => com_login [task] => login [] => 1 )Crape
Hmmm. Your still not picking up the token. I thought it might be a problem with the regex but I tested it and it definitely works. Comment out the post fields part of the code and dump $ret and $spoof to see what you have.Sternick
Thanks again for the help. I am not picking it up at all, when I try to print $ret and $spoof I simply get "Array()." Are there any extensions that I need to enable on my server besides curl?Crape
Just a little more info, I ran var_dump on those variables and got this: "array(0) { } string(0) ""."Crape
OK. There seem to be a couple of issues. First, your cURL is not working. I tried the code you posted and everything works, but it does have a bug. The code does pick up the token and login in the user, but the session does not seem to be accessible, I don't think it is transfering the cookie properly. I am still looking for a solution.Sternick
Add in a print_r ($spoof); after the first cURL section and a print_r ($postfields); at the end so you can debug why you are not getting the token, but this code definitely does that.Sternick
I tested cURL on my server using a test script and it is working perfectly, however I am unable to get the token from Joomla. Is there anything in particular I have to do to joomla to get this to work? I also added those two functions to my script and I am not getting anything for spoof or the token field.Crape
The only other thing I can think of is that the URL you are using doesn't have a login form on the page. You don't need to do anything to Joomla for this to work. This definitely works for getting the token and creating a login. Once you get to that point we can figure out how to access the logged in session.Sternick
Alright, I managed to get the token. I set the URL to www.mysite.com/joomla/index.php?option=com_user&view=login. Now, if I add print_r($postfields); I get this: "Array ( [username] => myuser [passwd] => mypass [lang] => [option] => com_login [task] => login [5e6901469c005288d205d631a1cdb7f7] => 1 )."Crape
I noticed that the token stays the same each time I run the script, even if I reset my browser. Shouldn't the token be changing each time I run the script if I reset my browser? At least I am getting something for the token field at this point.Crape
I noticed the same thing. You have to add curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE ); to the first curl instance. Now I need to figure out how to access the session once you have sent the post info to the login script.Sternick
Ok, I added curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE ); right after curl_setopt($ch, CURLOPT_HEADER, FALSE );. It looks like a new unique token is being generated each time the form is submitted.Crape
Ok, as I suspected, the curl was doing everything right, but the session was not being transferred to the browser. This is why you couldn't then go to the link and be logged in, but you could go in to the admin and see a user session logged in. I am going to post a new answer with the code.Sternick
I moved the print to the bottom of the page and stopped getting the header errors - but still not logged in. I do see the user logged in in admin - so i guess that's a good sign. Cookies are enabled and tried both chrome and safariAlbatross
The first error was likely due to whitespace before or after the opening or closing PHP tags. As for the user not being logged in, if you are seeing the session in the admin, then most likely there is an issue with the cookie. Take a look and see what is being stored in the cookie if anything at all.Sternick
Thanks for getting back to me. The cookie file itself has two strings stored in it that gets updated each time the script is run. But my print_r($cookie); is returning Array ( [0] => )Albatross
If that is all you are getting, you are missing a value. Take a look and see what is in $ret and $m.Sternick
for $m I just get "Array" If I echo $ret this is what I get HTTP/1.1 100 Continue HTTP/1.1 301 Moved Permanently Date: Sat, 17 Nov 2012 04:10:44 GMT Server: Apache/2.2.10 (Unix) mod_ssl/2.2.10 OpenSSL/0.9.8i DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 X-Powered-By: PHP/5.2.9 P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"Albatross
There is another dynamic hidden field in my form that I don't see referenced in the post data <input type="hidden" name="return" value="aW5kZXgucGhw">Albatross
There's your problem - the URL you are using is wrong. The one you are using has a 301 redirect. The hidden field you are seeing is one of the items that is being picked up by the code. That is the unique token required for logging in.Sternick
I see that after login there is a redirect to mysite.com/index.php?option=com_userI tried adding curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); and the page now goes to that redirect URL and says I'm logged in but as soon as I click on something I see I am not really logged in.Albatross
The full 301 message I get is HTTP/1.1 100 Continue HTTP/1.1 301 Moved Permanently Date: Sat, 17 Nov 2012 14:37:02 GMT Server: Apache/2.2.10 (Unix) mod_ssl/2.2.10 OpenSSL/0.9.8i DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 X-Powered-By: PHP/5.2.9 P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM" Location: http://www.mysite.com/index.php?option=com_user&view=login Content-Length: 0 Content-Type: text/html the URL I am using in the php script is the same as the redirect location. I guess I'm a little confused ;(Albatross
If I just do a normal frontend login the req url is mysite.com/index.php?option=com_user and that redirects to mysite.com/index.phpAlbatross
A
0

I got this working a different way (after a day of re-writing code and trying different things). First of all, be sure the php file is in your root Joomla directory. If token and sign in work but your browser isn't getting the cookie put the cookie code BEFORE the post code. Did that and it works fine. Thanks again Brent for the help.

<?php
$uname = $_GET['username'];
$upswd = $_GET['password'];
$url = "http://www.myJoomlaSite.com";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE );
curl_setopt($ch, CURLOPT_COOKIEJAR, realpath('./cookie.txt'));
curl_setopt($ch, CURLOPT_COOKIEFILE, realpath('./cookie.txt'));
curl_setopt($ch, CURLOPT_HEADER, TRUE );
$ret = curl_exec($ch);
if (!preg_match('/name="([a-zA-z0-9]{32})"/', $ret, $spoof)) {
    preg_match("/name='([a-zA-z0-9]{32})'/", $ret, $spoof);
}

// Get logged in cookie and pass it to the browser
preg_match('/^Set-Cookie: (.*?);/m', $ret, $m);
$cookie=explode('=',$m[1]);
setcookie($cookie[0], $cookie[1]);

// POST fields
$postfields = array();
$postfields['username'] = urlencode($uname);
$postfields['passwd'] = urlencode($upswd);
$postfields['option'] = 'com_user';
$postfields['task'] = 'login';
$postfields[$spoof[1]] = '1';
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$ret = curl_exec($ch);
?>
Albatross answered 18/11, 2012 at 3:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.