News:

SMF 2.1.4 has been released! Take it for a spin! Read more.

Main Menu

SMF integration help

Started by danp_canucks, July 07, 2008, 05:08:16 PM

Previous topic - Next topic

danp_canucks

I'm trying to manually set the log in cookie.

I know the

memberName
password / passwordHash  (from login form submission)
session_id()
 

I'm using smf_api.php but it does not work.

Can someone please help
PHP / .NET / DB Design and Development
Custom CMS Design
Shopping Cart Development
CMS component Development
Web Graphics / Flash Design

danp_canucks

#1
Ok I think I need to clear up my previous post.  So here is exactly what I'm trying to do.

On the front end of the site I'm displaying a Login Form.  The login form is custom built, with specially setup error messages and display settings depending on the type of user that logs in, this is managed by my CMS.  Therefore I cannot use the SSI function to display the login form.

On submission the username password information are currently not hashed, however, I can use a javascript function to hash the password / username / session information to hash the data on submission.  I am planning on using the following SHA1 algorithm to perform the hash.  The algorithm is featured on:

http://www.movable-type.co.uk/scripts/sha1.html [nofollow]

I don't know if this algorithm is compatible with the algorithm used by SMF, if it's not, can I use the JS SHA1 algorithm that SMF uses without infringment (this is a commercial product that will be resold)?

I was thinking about having the form submit to "integrate.php?action=login2"

and have the following code on the integrate.php page


FORM PAGE CODE:



<script>

var session=SET SESSION FROM PHP

function validateLogin(){

  var uname=$('username').value;
  var pass=$('password').value;

  $('password').value=(sha1(uname+password+session) //or some other variation;

}

function sha1(msg){

   SHA1 FUNCTION FROM http://www.movable-type.co.uk/scripts/sha1.html

}

</script>


<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
<td align="left" valign="top"><table width="296" border="0" cellspacing="0" cellpadding="0">
<tr>
  <td colspan="2"><img src="images/join_top.jpg" border="0" usemap="#Map"></td>
</tr>
<tr>
  <td width="142"><img src="images/join_bottom_l.jpg" border="0" usemap="#Map2"></td>
  <td width="154" align="left" valign="top" background="images/join_bottom_r.jpg">
 
  <table width="100%" border="0" cellspacing="1" cellpadding="1">
<form method="POST" id='loginForm' action="".WEB_ROOT_FRONT."/integrate.php?action=login2" onSubmit="return validateLogin(this);">

  <tr>
<td width="74%"><div class="fieldHolder">
  <input name="username" id="username" type="text" class="textInput" value="Username" />
</div>
  </td>
  </tr>
  <tr>
<td>
<div class="fieldHolder">
  <input name="password" id="password" type="password" class="textInput" value="Password" />
</div>
  </td>
  </tr>
  <tr>
<td align="right"><a href="".WEB_ROOT_BASE_FRONT."/forum/index.php?action=reminder"><font class="ForgotLink">Forgot your password?</font></a>&nbsp;&nbsp;&nbsp;<br>
  <a href="javascript: $('loginForm').submit()"><img src="images/login.jpg" width="73" height="23" hspace="10" vspace="5" border=0></a></td>
  </tr>
 
</form>
</table>
</td>
</tr>
</table>









INTEGRATE.PHP CODE


<?

//include CMS settings
require_once("inc/config.php");


//redirect people away from this page as they should not be looking at it directly.

if (basename($_SERVER['PHP_SELF']) == 'integrate.php')
{
   header('Location: ' . WEB_ROOT_FRONT);
   die;
}

define('SMF_INTEGRATION_SETTINGS', serialize(array(
//  'integrate_reset_pass' => 'reset_pass_function',
  // 'integrate_exit' => 'exit_function',
//  'integrate_logout' => 'logout_function',
   'integrate_login' => 'CMS_Login'
//  'integrate_validate_login' => 'validate_login_function',
   
)));


//include SMF settings (I don't think that there is any conflict)
require_once('../forum/SSI.php');


$context['siteurl'] = WEB_ROOT_FRONT;


function CMS_Login($uname, $pass, $time){

//PREFORM CMS LOGIN FUNCTIONALITY HERE
        //SET CMS LOGIN FUNCTIONALITY HERE


}


?>



Once this runs I need to redirect the user back to the page on which they tried to log in.  This will work for the CMS, and I think that SMF supports the same functionality.

Please let me know if I'm using the integration hooks properly, and if not what can I do to make this happen.









PHP / .NET / DB Design and Development
Custom CMS Design
Shopping Cart Development
CMS component Development
Web Graphics / Flash Design

danp_canucks

Is there something wrong with what I'm asking, or is this just something that cannot be done.  I am really falling behind on this project, and any input would be greatly appreciated.

                                                                             Thank You
PHP / .NET / DB Design and Development
Custom CMS Design
Shopping Cart Development
CMS component Development
Web Graphics / Flash Design

Orstio

If you want permission to redistribute code, you need to send an email to info at simplemachines.org.

If you are submitting data to SMF's login system, you don't actually need to submit it pre-hashed.  It is true that SMF does this natively, but SMF will also understand an unhashed password, and hash it before comparing it to the database value.

You are using the integration hooks correctly, except for the inclusion of SSI.php instead of SMF's index.php.  Submitting the login to SSI.php?action=login2 will not give you any results, because SSI has no idea what to do with "action=login2".  The array that determines those actions and results is in SMF's index.php.

danp_canucks

Thank You  Orstio, I appreciate the response.

However,  I don't want the user to be redirected to SMF upon login into the CMS, all I want to do is set the login cookie and authenticate the user with SMF so that if they decide to go to the SMF section on the site at some point during their visot they will not be asked to log in again.

Is this functionality supported by SSI, or do I need to use the API.

PHP / .NET / DB Design and Development
Custom CMS Design
Shopping Cart Development
CMS component Development
Web Graphics / Flash Design

danp_canucks

I am having problems with the call to integrate.php?action=login2.  It seems that after the form is submitted I get redirected to "forum/index.php" and my CMS login function does not get called.  However, I do get logged into SMF properly.

Here is the code for integrate.php:




require_once("myCMS/inc/config.php");



define('SMF_INTEGRATION_SETTINGS', serialize(array(
//  'integrate_reset_pass' => 'reset_pass_function',
  // 'integrate_exit' => 'exit_function',
//  'integrate_logout' => 'logout_function',
   'integrate_login' => 'myCMSLogin'
//  'integrate_validate_login' => 'validate_login_function',
   
)));

function myCMSLogin($uname, $pass, $time){

$array=array("user"=>$uname, "passwrd"=>$pass);

$Controller=new myCMSControllerMain(false);
$result=$Controller->doAction( array('module'=>'members', 'object'=>'membersModule', "action"=>'checkUserLogin'), $array );

}


require_once('forum/index.php');



//redirect people away from this page as they should not be looking at it.
/*
if (basename($_SERVER['PHP_SELF']) == 'home.html')
{
   header('Location: ' . $siteurl);
   die;
}

*/






please tell me what I'm doing wrong
PHP / .NET / DB Design and Development
Custom CMS Design
Shopping Cart Development
CMS component Development
Web Graphics / Flash Design

Orstio

Is there anything in your error log?  It looks like SMF is exiting instead of returning, which would be normal behaviour if there was an error.

danp_canucks

#7
Orstio, Thank You again for your reply.  You are absoutely correct, I had an error in my CMS login function that was messing everything up.  I can't thank You enough for trying to help me, this is greatly appreciated.  I will definetly stick around these boards in the future and try to help out whomever I can with my limited knowledge. 

However there is still a problem.


I modified the code on "index.php" of the forum to be as follows to fix the previous error.  I decided to embed the integration code directly on SMF's index.php page, instead of using the integrate.php page.


forum/index.php



define('SMF_INTEGRATION_SETTINGS', serialize(array(
//  'integrate_reset_pass' => 'reset_pass_function',
  // 'integrate_exit' => 'exit_function',
//  'integrate_logout' => 'logout_function',
   'integrate_login' => 'myCMSLogin'
//  'integrate_validate_login' => 'validate_login_function',
   
)));



function myCMSLogin($uname, $pass, $time){

$array=array("username"=>$uname, "password"=>$pass);

require("../inc/config.php");


$Controller=new myCMSControllerMain(false);

        //where to redirect after login
$_SESSION['login_url']=WEB_ROOT_BASE_FRONT."/home.html";

return $result=$Controller->doAction( array('module'=>'members', 'object'=>'membersModule', "action"=>'setUserSessionData'), $array );


}



The problem is that the login function for my CMS sets up some $_SESSION variables.  What happens when the login2() function for SMF runs, it changes the $_SESSION id, and all the session variables set up by the CMS login function are no longer visible.  Whats even worse is the fact the the session id gets changed after the integration hook runs, so I have no way to copy my session variables to the new session id, and the CMS login data is lost.

Because of this I think I will have to change the validation on myCMS to use the cookie that is set by SMF to set the session variables.  I hope I'm wrong on this and there is some way to merge the old session and the new one, but in case I'm right here is another solution.  Unfortunately I need help with this one too.

Here is the code that I'm planning to use to authenticate the access levels for the user once they are authenticated by SMF and the cookie is set.



$result=$Controller->doAction( array('module'=>'members', 'object'=>'membersModule', "action"=>'setUserSessionData2'), false );


function setUserSessionData2(){


   if(isset($_COOKIE['SMF_COOKE'])){

         //get Data From Cookie
         $data=unserialize($_COOKIE['SMF_COOKE']);
         $ID_MEMBER=$data[0];
         
         //THS IS WHERE I NEED HELP I NEED TO SET $pwHash=SMF password field

         $pwHash=getPW($data[1]);


         //note cms_members is the SMF members table with several added fields
         $sql="SELECT some data ..........  FROM
                                          cms_members cm
                                   INNER JOIN
                                          cms_access_tbl cat
                                   ON cm.ID_MEMBER=cat.ID_MEMBER
                                 
                     WHERE cm.MEMBER_ID='".$ID_MEMBER."' AND passwd='".$pwHash."'";
         
                   $result=dbQuery($sql);
                   if(dbNumRows($result)){

                             //DO CMS LOGIN STUFF

                   }
                   else{

                            return false;                             

                  }



   }
   else{

        return false;

   }

}



//This function will take the cookie data and make it equal to the password hash
//that's in the database. 

//I need some help with this one

function getPW($pwHash){

         //PLEASE HELP HERE

       $hash=do some stuff to $pwHash

       return $hash

}




PHP / .NET / DB Design and Development
Custom CMS Design
Shopping Cart Development
CMS component Development
Web Graphics / Flash Design

Orstio

QuoteThe problem is that the login function for my CMS sets up some $_SESSION variables.  What happens when the login2() function for SMF runs, it changes the $_SESSION id, and all the session variables set up by the CMS login function are no longer visible.  Whats even worse is the fact the the session id gets changed after the integration hook runs, so I have no way to copy my session variables to the new session id, and the CMS login data is lost.

That's not the whole picture.  SMF cleans the current session, and replaces it with a SMF-only session in order to counter a possible PHP session fixation exploit.  This happens on login, and I believe after every post.

If your CMS relies on session data, the trick is to write that data to SMF's session AFTER the login.

Or....

Force SMF to use your CMS login.

Check the integrate_verify_user hook to find out how that works.  With this hook, you can get SMF to validate against an alternative authentication, like a cookie from your CMS.

danp_canucks

#9
Orstio, once again Thank You for the reply.

You have confirmed my suspicions, that I will need set up the CMS login session outside of the integration hook.  (It would be nice if SMF ran the integration hook after the new session_id was assigned so that it could be used to set up CMS session vars.

But I think I understand the reasons for not doing so.  Thus I will continue with the solution I planned out in the above post.  Where the SESSION is checked or set on every page of the CMS.

I will set the CMS session from the cookie that was set by SMF upon login.

Here is the code that I'm using


public function setUserSessionData2(){

           if(isset($_SESSION['member']) && count $_SESSION['member'])
                 return true;


   if(isset($_COOKIE['SMF_COOKE'])){

//get Data From Cookie that was set by SMF upon login

$data=unserialize($_COOKIE['SMF_COOKE']);
$ID_MEMBER=$data[0];

$pwHash=$this->$data[1];


//note cms_members is the SMF members table with several added fields
$sql="SELECT ku.*, kg.groupName as kapelleGroupName
FROM
kapelle_users ku
INNER JOIN
kapelle_group_tbl kg
ON
ku.kapelleGroupID=kg.groupID
WHERE
MEMBER_ID='".$ID_MEMBER."' LIMIT 1";

   $result=dbQuery($sql);
   if(dbNumRows($result)){
   
    $row=dbFetchAssoc($row)
//Check if the hash from the Database is equal to the Cookie Hash set by SMF
if(sha1($row['passwd'] . $row['passwordSalt'])==$pwHash){

                                       //set CMS session vars

$_SESSION['var']=$row['var'];
$_SESSION['var']=$row['var'];
                                        $_SESSION['var']=$row['var'];
                                        ................................................

                                        return true;


}
else{
return false;
}
   }
   else{

return false;                             

  }



   }
   else{

return false;

   }

}






I'm assuming the following


$data=unserialize($_COOKIE['SMF_COOKIE'])
$pwhash=$data[1];

$SMFHash=sha1(passwd.passwordSalt) from the SMF members table 


if($pwhash==$SMFHash) //This is the Assumption about how the Cookie is set.
       return true
else
      return false //  authentication failed



I have not tested this solution yet, but I'm hopeful that it will work.  Please let me know if I'm way off base somewhere.  I will post the results of this once I test.

Once again Thank You for helping me on this, I might still be able to save my behind on this project :)
PHP / .NET / DB Design and Development
Custom CMS Design
Shopping Cart Development
CMS component Development
Web Graphics / Flash Design

danp_canucks

Ok.  The above described method works pretty well.  The only think I would like to change if possible

On the Login page if the user enters a wrong password they are taken to SMF's login error page.  What I would like is for them to be redirected to the page from which they made the submission.

Please tell me if this is possible
PHP / .NET / DB Design and Development
Custom CMS Design
Shopping Cart Development
CMS component Development
Web Graphics / Flash Design

Orstio

#11
I wouldn't even bother authenticating in SMF.  Seems redundant to authenticate in both, no?

define('SMF_INTEGRATION_SETTINGS', serialize(array(
//  'integrate_verify_user' => 'CMS_verify_user', 
   )));

function CMS_verify_user ()
{

$ID_MEMBER = (int) $_SESSION['ID_MEMBER'];
return $ID_MEMBER;

}


danp_canucks

#12
That's very true.  The reason why I wanted to use SMF's authentication is because it appears to be far more robust and secure then then authentication procedures that I wrote for my CMS.  Although for some Login Forms used throught the CMS driven site I will definetly use the hook you just provided me with, and forgo the SMF authentication.  I think for the majority of the login forms I would like to use SMF's authentication procedures with the integration hooks that we outlined above, even though the authentication is a bit repetitive, as they seem to be very secure.

I'm back on track with this project :)  I was not at all expecting the level of support that I received on this issue.  The help that was offered was precise, informative, and extremely helpful.  I was quite hesitant to use SMF at the beginning of the project as I had never used it before, but the client insisted.  I would like to say that because of the support and the features offered by SMF, it will become "the" forum application I use in my future development ventures.

                                                                          Thank You       
PHP / .NET / DB Design and Development
Custom CMS Design
Shopping Cart Development
CMS component Development
Web Graphics / Flash Design

henryford

Orstio and Canucks

Why not handle the session data loss issue using a javascript code.
Look here - http://www.thomasfrank.se/sessionvars.html
Seems like a quick fix to all these data loss issue. In my case, i loose data from session only when i am using Firefox. In IE the CMS+SMF works like a charm with no loss in any session data.

rorrito

hiii

i read  and read and red but i cant understadn how to integrate in to my own app


i am develop in codecharge studio... theres no problem using the member table form SMF .. with my own apps .... my problem is when i want to make a record to my db .. i want to get the MEMBER_ID from SMF to record in to my own app


i have a table of user in my db  using id_socio as key   


i want to log in using SMF to get the user logged .. when the user make a record to my app get the MEMEBERID form smf ..


how can i do this??


or is very simple to make the bridge ??


thanks

Orstio

Quote from: henryford on July 12, 2008, 01:59:12 PM
Orstio and Canucks

Why not handle the session data loss issue using a javascript code.
Look here - http://www.thomasfrank.se/sessionvars.html
Seems like a quick fix to all these data loss issue. In my case, i loose data from session only when i am using Firefox. In IE the CMS+SMF works like a charm with no loss in any session data.

I wouldn't refer to the destruction of the session on login as "loss".  SMF purposely deletes the session information in order to make sure that there is no session fixation.  If you have modified this somehow so that there is session fixation, then you have opened a security hole in your forum.

henryford

It is however strange that SESSION data is lost only in Firefox and not in IE (an Crazy Browser) !
I have smf at www.mysite.org/smf
My Integration is like this . (I have renamed SMF's index.php into index.inc.php) and i am using a index.php file that looks like this : ($_SESSION['user_name']  is populated at the previous CMS login screen)

<?php
include($_SERVER['DOCUMENT_ROOT'] ."/classes/sessions.php");
include($_SERVER['DOCUMENT_ROOT'] ."/classes/config.php");
//session_start();
//include($_SERVER['DOCUMENT_ROOT'] ."/classes/login_check.php");
include($_SERVER['DOCUMENT_ROOT'] ."/classes/menu.php");




if($_SESSION['user_name'] != NULL)
{

   define('SMF_INTEGRATION_SETTINGS', serialize(array(
      'integrate_verify_user' => 'integrate_verify_user',
   )));

   function integrate_verify_user () {

      global $db_name, $db_prefix, $sql, $userdata;


      $query = mysql_query("SELECT ID_MEMBER FROM {$db_prefix}members WHERE memberName = '$_SESSION[user_name]'");

      if (!(list($ID_MEMBER) = mysql_fetch_row($query))) {
         mysql_query("INSERT INTO {$db_prefix}members
            (memberName, realName, passwd, emailAddress, dateRegistered, ID_POST_GROUP, lngfile, buddy_list, pm_ignore_list, messageLabels, personalText, websiteTitle, websiteUrl, location, ICQ, MSN, hideEmail, signature, avatar, usertitle, memberIP, memberIP2, secretQuestion, additionalGroups)
            VALUES ('$userdata[username]', '$userdata[forum_name]', '$userdata[password]', '$userdata[email]', ".time().", '4', '', '', '', '', '', '', '', '', '', '', '1', '', '', '', '', '', '', '')");
         $ID_MEMBER = mysql_insert_id();
      }
      return $ID_MEMBER;
   }



   # Include the original index.php
   include($_SERVER['DOCUMENT_ROOT'] . "/smf/index.inc.php");

}

else

{

   # Include the original index.php
   include($_SERVER['DOCUMENT_ROOT'] . "/smf/index.inc.php");

}




?>


This works pretty well (both in  FF and IE) and when you go from CMS to SMF, user looks logged in.

The moment you click on anything in the forum (in FF ONLY. IE is fine) , Member is logged out from Forum ! He still is logged into the CMS part.

Orstio,

Do you mean that just after the integrate_verify_user hook, we should use populate SMF session variable for member id with $ID_MEMBER ? 

How do you do that and what is the name of the SMF Session variable ?

I think i am at a loss here. How do you populate the SMF Session variables with some data so that although SMF will not allow session fixation, session values will still be available.

Thanks
HF






Orstio

The session destruction is done on certain events, like logging into SMF or posting a message.

The integrate_verify_user hook is done on each and every page load, so is not related at all to the session destruction.

What I am saying is that if somebody logs into SMF using the SMF login (not the integrate_verify_user hook), then their session will be destroyed and recreated, which results in non-SMF session info getting destroyed (not lost, but purposely deleted).


henryford

Quote from: Orstio on July 11, 2008, 11:56:31 PM
QuoteThe problem is that the login function for my CMS sets up some $_SESSION variables.  What happens when the login2() function for SMF runs, it changes the $_SESSION id, and all the session variables set up by the CMS login function are no longer visible.  Whats even worse is the fact the the session id gets changed after the integration hook runs, so I have no way to copy my session variables to the new session id, and the CMS login data is lost.

That's not the whole picture.  SMF cleans the current session, and replaces it with a SMF-only session in order to counter a possible PHP session fixation exploit.  This happens on login, and I believe after every post.

If your CMS relies on session data, the trick is to write that data to SMF's session AFTER the login.

Or....

Force SMF to use your CMS login.

Check the integrate_verify_user hook to find out how that works.  With this hook, you can get SMF to validate against an alternative authentication, like a cookie from your CMS.

Could you elaborate a bit on the following two aspects of your suggestion

If your CMS relies on session data, the trick is to write that data to SMF's session AFTER the login.

Or....

Force SMF to use your CMS login.

How do i write data to SMF's session after the login. Could you point me towards the required hook ?

Your advice is always greatly appreciated.

HF

Orstio

QuoteHow do i write data to SMF's session after the login. Could you point me towards the required hook ?

I thought you were using the integrate_verify_user hook?

Advertisement: