Passing logon credentials on URL with a Wordpress to SMF bridge in use

Started by oskar866, May 22, 2025, 10:55:18 AM

Previous topic - Next topic

oskar866

Over the past few days I've been modifying the WP2SMF Bridge that was originally written by DSR! (9 years ago) so that it now works on the latest WordPress, PHP and SMF (WP 6.8.1, PHP 8.8.28 and SMF 2.1.4).  I've also added some logging to the PHP so I can work out what's going on (and not going on ;) ).  The result is that I can now add a user to the SMF database when a user logs into my WordPress website, the passwords are synced and SMF users are automatically accepted onto the forum, no need to register or await admin approval.  This then got me wondering if I could integrate WP and SMF even further...

What I'd like to do on the website is for a link to the SMF forum to be available to logged on users, this link would take them to the forum without the need for them to log in (with the same username and password and they just used to log into the website). Is it possible to pass this information in the URL?  Or, is there another way to avoid this second logging on?

Thanks

Sesquipedalian

The best way to do that would be to use the integrate_verify_user hook. That hook is designed for exactly this purpose.
I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.

Kindred

PHP 8.8 ?? ??


8.5 is the version currently in development.... and we know that SMF 2.1.4 starts to have issues with php8.4
Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."


oskar866

Continuing with my project of a SSO from WordPress to SMF, I was working on a method to pass a token from a Code Snippet in WordPress to a new php file at the root of my test SMF forum.  If the tokens match then the username and password of the SMF user is obtained, a login cookie created at the forum loaded.  What I could do with some help with is the part of the code where the SMF database is queried for the users password and salt, I'm not getting anything back, it's like the DB isn't being queried and the script stops/bombs out.  Can anyone guide me why this should be, I guess the credentials to access the DB are obtained when SSI.php is called.  I added some echos to try and see where it's failing.  Any ideas?

The code is:

// sso_login.php for SMF
// Place this file in your SMF root directory
global $smcFunc;

define('SMF', 1);
require_once('SSI.php');
require_once('Sources/LogInOut.php');

// Shared secret must match the value in the external system (e.g. WordPress)
$shared_secret = 'not-my-real-secret';

// Read token from GET
$token = isset($_GET['token']) ? $_GET['token'] : '';
if (!$token) die('Missing token.');

// Decode token
$data = json_decode(base64_decode($token), true);
if (!is_array($data) || !isset($data['user'], $data['expires'], $data['sig'])) {
    die('Malformed token.');
}
echo "user = " . $data['user'] . '<br>';
echo "sig = " . $data['sig'] . '<br>';

// Validate signature
$expected_signature = hash_hmac('sha256', $data['user'] . $data['expires'], $shared_secret);
echo "exp = " . $expected_signature . '<br>';
if (!hash_equals($expected_signature, $data['sig'])) {
    die('Invalid token signature.');
}
echo "hash matches<br>";

// Validate expiry
if ($data['expires'] < time()) {
    die('Token expired.');
}
echo "token not expired<br>";
$username = $data['user'];



// Look up user in SMF database
$request = $smcFunc['db_query']('', '
    SELECT id_member, passwd, password_salt
    FROM {db_prefix}members
    WHERE member_name = {string:username}
    LIMIT 1',
    array(
        'username' => $username,
    )
);
echo "userame = " . $username . "<br>";

echo "number of rows = " . $smcFunc['db_num_rows']($request) . "<br>";

if ($smcFunc['db_num_rows']($request) === 0) {
    die('User not found in SMF.');
} else {
    list($id_member, $passwd, $salt) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);

    echo "User found: ID = $id_member<br>";
}

setLoginCookie(60, $id_member, sha1($passwd . $salt));

// Redirect to forum
redirectexit('index.php');

This is what is echoed:

user = wibble
sig = 59693224cbd88666121e11934a3f3f3103bba0b305819575d887cf32e5789299
exp = 59693224cbd88666121e11934a3f3f3103bba0b305819575d887cf32e5789299
hash matches
token not expired

As you can see, I don't get anything after $request.  Any thoughts?  Thanks

oskar866

I've now worked out how to obtain the info from the database, the issue now is that when the script redirects the webpage it looks like the cookie isn't being set/used, the login screen appears, I'm not sure why.  I'll carry on with this post in the 'SMF Coding Discussion' forum as it's now nothing to do with bridges, more to do with coding.

If anyone reads this and would like to know what was wrong with my initial code, it was to do with the first few lines:

// sso_login.php for SMF
// Place this file in your SMF root directory

$ssi_guest_access = true;
if (!file_exists(dirname(__FILE__) . '/SSI.php'))
    die('Cannot find SSI.php');

require_once(dirname(__FILE__) . '/SSI.php');
require_once($sourcedir . '/LogInOut.php');
require_once($sourcedir . '/Subs-Auth.php');

// Shared secret must match the value in the external system (e.g. WordPress)

Advertisement: