Jump to content

Remote Login


Nils

Recommended Posts

I would like to allow my users to log into an external site using their IPB account details. What is the best way to validate IP.Board logins (username + password) remotely?

I would have expected there to be an XML-RPC method or something like that, but I can't find anything in the documentation. Does no such method exist or is it just not documented?


(I already posted this in technical support forums, but this forum may be more appropriate)

Link to comment
Share on other sites

The way I would do it is create a php page somewhere on your server which returns XML or JSON.

Something like:

<?php /* Variables */ $email = $_GET['email']; $md5Pass = $_GET['md5pass']; /* Init IPB */ define( 'IPS_ENFORCE_ACCESS', TRUE ); define( 'IPB_THIS_SCRIPT', 'public' ); require_once( './initdata.php' );/*noLibHook*/ require_once( IPS_ROOT_PATH . 'sources/base/ipsRegistry.php' );/*noLibHook*/ require_once( IPS_ROOT_PATH . 'sources/base/ipsController.php' );/*noLibHook*/ $registry = ipsRegistry::instance(); $registry->init(); /* Get Member */ $member = IPSMember::load( $email, 'none', 'email' ); if ( !$member['member_id'] ) { echo json_encode( array( 'success' => FALSE, 'message' => 'NO_MEMBER' ) ); exit; } /* Authenticate */ if ( IPSMember::authenticateMember( $member['member_id'], $md5Pass ) ) { echo json_encode( array( 'success' => TRUE, 'message' => '' ) ); } else { echo json_encode( array( 'success' => FALSE, 'message' => 'BAD_PASS' ) ); }


































Link to comment
Share on other sites

Thanks, I am using a slightly adapted version of that now.

One question though - does IP.Board hash the raw password or the version with entities? E.g. if my password is "<>", what exactly does IP.Board use as the md5 hash? Is it md5('<>') or md5('&lt;&gt;')?

This would make things quite a bit more complicated, since I'd have to do some otherwise unnecessary postprocessing of the string before hashing it...

Link to comment
Share on other sites

Funny enough, we have documentation for that. ;)

http://community.invisionpower.com/resources/documentation/index.html/_/developer-resources/miscellaneous-articles/passwords-in-ipboard-r501

This article describes the characters in the password that are converted, in the event you need to do the same on your end for comparison

http://community.invisionpower.com/resources/documentation/index.html/_/developer-resources/miscellaneous-articles/login-modules-r7

Link to comment
Share on other sites

  • 10 months later...

Sure,

https://www.invisionpower.com/support/guides/_/advanced-and-developers/miscellaneous/passwords-in-ipboard-r130

and

http://www.invisionpower.com/support/guides/_/advanced-and-developers/integration/login-modules-r42

Also, you may wish to either utilize IPB's built-in brute force prevention (see admin/sources/loginauth/login_core.php, starting around line 287 -- you might be able to make use of it without duplicating code by instantiating the internal login class and calling authenticate() on that) or restrict access to your script so that only the IP of your other application can access it. This way people cannot brute force your user's passwords, which is probably a Good Thing™.

EDIT: Ninja'd by Ryan Ashbrook, but I'll keep this here anyway since it includes some information I feel is important and not covered above.

Link to comment
Share on other sites

  • 4 months later...

If you're looking to authenticate a user against a remote system, then it would be worth looking into SSO, provided the two systems are on the same domain.

http://www.invisionpower.com/support/guides/_/advanced-and-developers/integration/single-sign-on-sso-r209

Otherwise - a new Login Method or utilizing IPS Connect would be your best bet. I would recommend, however, posting in the customization forums if you need assistance with your custom code.

http://community.invisionpower.com/forum/310-product-modifications/

Link to comment
Share on other sites

  • 1 year later...
  • 2 months later...

Hi, It use IPS Connect key for add security, using HTTPS strongly recommended

* PHP 5.3 required for crypt function

<?php
/**
 * @author		<a href='http://www.skinod.com.com'>Skinod.com.</a>
 * @copyright	(c) 2015 skinod.com
 */

$_SERVER['SCRIPT_FILENAME']	= __FILE__;
$path	= '';

require_once $path . 'init.php';
\IPS\Session\Front::i();

$key = md5( md5( \IPS\Settings::i()->sql_user . \IPS\Settings::i()->sql_pass ) . \IPS\Settings::i()->board_start );

$login_type = 'email';

/* uncomment for more security  */
// $ip_address = array('127.0.0.1', 'x.x.x.x'); // EDIT THIS LINE!!
// if(in_array($_SERVER['REMOTE_ADDR'], $ip_address) !== TRUE) {
	// echo_json(array('status' => 'FAILD', 'msg' => 'BAD_IP_ADDR'));
// }

/* -~-~-~-~-~-~ Stop Editing -~-~-~-~-~-~ */

if( !\IPS\Request::i()->do || !\IPS\Request::i()->id || !\IPS\Request::i()->key || !\IPS\Login::compareHashes( \IPS\Request::i()->key, md5($key . \IPS\Request::i()->id))) {
	echo_json(array('status' => 'FAILD', 'msg' => 'BAD_KEY'));
}

$member = \IPS\Member::load( \IPS\Request::i()->id, $login_type );

if( !$member->member_id ) {
	echo_json(array('status' => 'FAILD', 'msg' => 'ACCOUNT_NOT_FOUND'));
}

switch(\IPS\Request::i()->do) {
	case 'get_salt':
		echo_json(array('status' => 'SUCCESS', 'pass_salt' => $member->members_pass_salt));
	break;
	case 'login':
		if( \IPS\Login::compareHashes($member->members_pass_hash, \IPS\Request::i()->password) === TRUE ) {
			echo_json(
					array(
						'status' => 'SUCCESS',
						'connect_status'			=> ( $member->members_bitoptions['validating'] ) ? 'VALIDATING' : 'SUCCESS',
						'email'						=> $member->email,
						'name'						=> $member->name,
						'connect_id'				=> $member->member_id,
					)
				);
		}
	break;
}


function echo_json(array $arr) {
	echo json_encode($arr);
	exit;
}

use this like:

<?php

$ips_connect_key = 'b7705cb2cf70ee62efa97afab7a41f3b';
$remote_login = 'http://localhost/ips4/remote_login.php';

$email			= $_GET['email'];
$password		= $_GET['password'];

$key 			= md5($ips_connect_key . $email);

// fetch salt first
$res = json_decode(file_get_contents($remote_login . "?do=get_salt&id={$email}&key={$key}"), true);

$hash = crypt( $password, '$2a$13$' . $res['pass_salt'] );

$res = json_decode(file_get_contents($remote_login . "?do=login&id={$email}&key={$key}&password={$hash}"), true);

print_r($res);

 

 

login.php

 

remote_login.php

Link to comment
Share on other sites

Hey Sijad, I have been toying around with the code and it's works perfect.  Is it possible to redirect the person to my forum and auto login after they signup on the external form, BTW, my external form is really on my site just on a lander outside of my forum.  Thanks for anything you can clue me into :)

Link to comment
Share on other sites

  • 3 months later...

sijad, your script works perfectly for what i want but i was wondering if their was a way to make it return some of the users custom profile fields

an updated version of this script available here: https://github.com/sijad/IPS4RemoteLogin

you can fetch profile field like this:

http://localhost/ips4/remote.php?key={key}&id={user_id}&do=field&fgroup={profile_field_group_id}&fid={profile_field_id}

 

Link to comment
Share on other sites

thanks

in addition to the security already built in, i added an extra layer. Better safe than sorry.

<Files remotelogin.php>
 order deny,allow
 deny from all
 allow from 127.0.0.1
</Files>

this stops anyone except authorised ips from even accessing the file :)

Link to comment
Share on other sites

  • 1 year later...

Hello Sijad,

I have tried your code with IPS 4.1.17 but have issues.

After providing correct email and password I got this:

{"status":"SUCCESS","connect_status":"SUCCESS","email":"email@example.com","name":"Jibeji","connect_id":"2"}

But I am not logged into the Suite...

Link to comment
Share on other sites

  • 1 month later...

Hi,

I finaly found how to log in, here is what I do :

require_once(dirname(__FILE__).'/../forums/init.php');
$IPSLogin = new \IPS\Login\Internal;
$IPSLogin->init();

try {
         $member = $IPSLogin->authenticate(array('auth' => $_POST['username'], 'password' => $_POST['password']));
         if ($member) {
            $expire = new \IPS\DateTime;
            $expire->add( new \DateInterval( 'P7D' ) );
            \IPS\Request::i()->setCookie( 'member_id', $member->member_id, $expire );
            \IPS\Request::i()->setCookie( 'pass_hash', $member->member_login_key, $expire );
            \IPS\Request::i()->setCookie( 'hasJS', true, $expire );
            print '<html><head><meta http-equiv="refresh" content="0;URL=\''.$prev_url.'\'"></head></html>';
         }
      } catch (Exception $e) {
         blahblah
      }

Hope it helps.

Link to comment
Share on other sites

If it helps anyone, I'm using the following for now, though I'm sure there's a better way:

            if ($e->getMessage() == "login_err_bad_password")  {
                    print "Bad Password!";
            } else {
                    //print "Bad Account!";
                    print $e->getMessage();
            }

For NAME and EMAIL availability check:

//LOGIN Object
$IPSLogin = new \IPS\Login\Internal;
$IPSLogin->init();

//USERNAME in use (1=Unavailable)
$username_check = "TestAccount";
if ($IPSLogin->usernameIsInUse($username_check) == 1) {
    print ' || NAME: already in use.';
} else {
    print ' || NAME: available for use!';
}

//EMAIL in use (1=Unavailable)
$email_check = "test@test.com";
if ($IPSLogin->emailIsInUse($email_check) == 1) {
    print 'EMAIL: already in use.';
} else {
    print 'EMAIL: available for use!';
}

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...