Go Back   vb.org Archive > vBulletin Article Depository > Read An Article > vBulletin 3 Articles
FAQ Community Calendar Today's Posts Search

Reply
 
Thread Tools
Single Signin / Login Integration Tip
orbita
Join Date: May 2006
Posts: 1

 

Show Printable Version Email this Page Subscription
orbita orbita is offline 05-11-2006, 10:00 PM

Hi people, first post here, hope its useful

I've just installed vbulletin on a client site as they needed a forum/discussion facility and vbulletin provided good moderation facilities. They wanted existing users who were logged into the site not to have to log in again in order to use vbulletin.

I noticed there wasnt much help for this on the forum and quite a few posts asking how it could be done. Since I have solved part of the problem I thought it might be useful to share it with you.

Essentially the problem is to log in an existing user into vbulletin outside of the vbulletin environment so that when they access a vbulletin page it recognises them.

This, as you might imagine involves the use of cookies.

The way I have gone about it is to create an authentication handler in apache to be triggered when anyone tries to access a vbulletin page (i have vbulletin installed under /vb/)

Since we are using mod_perl, the httpd.conf directive looks a bit like this...

<Location /vb/>
AuthType BLAHType
AuthName BLAHName
PerlAccessHandler BLAH->login_to_vb
</Location>


So.. when a user asks for a vb page, first it runs the login_to_vb method in module BLAH. (but you could probably make this a php page or something else)

the login_to_vb script routine works as follows

1) it gets the currently signed in username and password (this will depend on the authorisation your website uses
2) it POSTs this information to /vb/login.php. In perl I do it like this...

my $browser = LWP::UserAgent->new;
my $response = $browser->post( $url, [
vb_login_username=>$user,
vb_login_password=>$pass,
do=>'login');


3) It reads the cookies from the header recieved back and the places them into the outgoing headers..

my $header = $response->headers;
my @cookies = $header->header('Set-Cookie');

foreach my $c (@cookies) {
$r->headers_out->add('Set-Cookie',$c);
}

4) Finally, it redirects the user to the page they were trying to access.

my $redir_url = "http://".$r->hostname.$r->uri;
my $pathinfo = join '&', ( map { "$_=$args->{$_}" } keys %{$args} );
$redir_url.= "?$pathinfo" if $pathinfo;
$r->headers_out->add("Location" => $redir_url);
$r->status(302);
$r->send_http_header;
Apache::exit;


BUT.. there is a problem...

vbulletin is clever, when you login, it registers your IP address against the session it creates for you. Next time you hit a vbulletin page it checks your IP against that session to make sure it is handing it back to the correct user.

If you look at the file includes/class_core.php you will find a SQL query around line 2460 that looks mostly like this...

if ($session = $db->query_first("
SELECT *
FROM " . TABLE_PREFIX . "session
WHERE sessionhash = '" . $db->escape_string($sessionhash) . "'
AND lastactivity > " . (TIMENOW - $registry->options['cookietimeout']) . "
AND ( (
host = '" . $this->registry->db->escape_string(SESSION_HOST) . "'
AND idhash = '" . $this->registry->db->escape_string(SESSION_IDHASH) . "'
)
OR host = '".$_SERVER['SERVER_ADDR']."' )
"))
{


If you modify the query to what I have here, the server will happily let you log in if the session originally came from the server IP address, regardless of the IDHASH or HOST address. This reduces security a little bit so if you are very security conscious you might need to adjust this to suit you better.


What else?

Well, you don't really want the script to log you in EVERY time you access a vB page - bit excessive. So I set an extra cookie with a timestamp and only log in if a certain time has passed since it last logged you in. I set this interval just lower than the timeout set in vbulletin so that it logs you back in just before the vbulletin timeout kicks in. You can hard code this or pull it out of the vbulletin database settings.

Obviously this just handles the login process.. You will need to find a way to keep the users details in sync. There are instructions for editing users details remotely on this site so I dont really need to cover that. One way though, would be to turn off user profile/password editing in the bulletin software and simply update the vbulletin user database from your existing application.

To make updates to the vbulletin user database you need to create a php file (say /vb/updateVB.php within your vb directory that you can call upon to make changes to the user table.

It would probably start something like this..
require_once('./global.php');
require_once('./includes/class_dm.php');
require_once('./includes/class_dm_user.php');

$userdm = new vB_DataManager_User($vbulletin, ERRTYPE_ARRAY);

$userdm->set('username', qpc_post('username'));
$userdm->set('password', qpc_post('password'));

etc...

Then from your application you can make GET requests to your script

eg: /vb/updateVB.php?do=new_user&username=blah&password=bl ah

Hope someone finds this of use.
regards, Tom
Reply With Quote
  #12  
Old 01-27-2007, 04:00 PM
Kalyse Kalyse is offline
 
Join Date: Sep 2006
Posts: 14
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by hornstar1337 View Post
This has been out since last year already https://vborg.vbsupport.ru/showthrea...n+non+vb+pages

I think that would have solved your solution/s already
Thats not what he is doing.
He has a site first, then Vb.

Not theother way round.
That link doesn help at all.
Reply With Quote
  #13  
Old 01-29-2007, 12:20 AM
dionak dionak is offline
 
Join Date: Feb 2006
Posts: 18
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Just curious, what perl script?

Quote:
Originally Posted by wcm View Post
Has anyone tried the Perl solution with 3.6? It looks like a very neat way to do this.

I am a little bit curious on how the final perl script looks.
This is really validating. I used a similar approach in a recent site. It's cgi-perl as opposed to mod_perl, mostly b/c when I started to build...I didn't know if I would have mod_perl on the destination server.

Orbita, I really like your approach. It's really clean (and would reduce my code a lot!).

I recently did a single sign-on for a site which included the site, vbulletin and mediawiki. Mediawiki uses PHP sessions, as opposed to cookies. I'm still puzzling how to tell if the user is logged into the site, vbulletin and mediawiki without checking every request (which I'm not doing, it would be extreme overhead).

I guess since the scenario described in your post only involves cookies, it's easy to set them all to expire at the same time so you don't have the session vs. cookie expiry synch issue I'm experienceing. Any ideas on that?

I had a lot of issue with the sessions in the VB integration which is why I chose the same method of using LWP::UserAgent to post to the registration and login scripts in VB.

To do registration, I created a form and corresponding script that processes the form and posts to the registration scripts for vbulletin and mediawiki using LWP::UserAgent. Same as login. It's a challenge though, because 3.6.4 changed the registration logic slightly and now I need to figure out how to accomodate the new logic. It looks like VB registration is now looking for a MD5 hash in the post to register.

Upon registration, the last bit of my custom code creates what I'm calling an 'application username' and 'application password'. The values are whatever the user registers with. These are used for the login, no matter how many times the user might change their password.

So when a user registers, their password is hashed into the 'password' and 'app_password' columns in my custom users table. When the user logs in, I check the submitted password against the 'password' column, then the 'app_password' is retrieved and used for the login request.

To handle the user profile information in vbulletin, I created a plugin that redirects the user to the site account page if they try to update their username or password. Updating both my app's users table and the vb_users table seemed both troublesome and a lot of work for this critical component.

Mediawiki turned out to be a lot easier once I wrapped my head around it. It has 'hooks', so I was able to write an Authentication plugin (called Authplugin in MW) that was a lot simplier. I set up a php script to read my site cookie and set a variable. If the variable is empty (the user isn't logged in) it authenticates the user using the site cookie.

It would be a heck of a lot easier to integrate Vbulletin if it had an authentication hook like this. Or maybe there is a way to do it that I haven't yet realized? There is the global_start for plugins.

Diona
Reply With Quote
  #14  
Old 03-02-2007, 03:12 AM
apn3a apn3a is offline
 
Join Date: Oct 2004
Location: Athens Greece
Posts: 39
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

does anyone have any idea how to integrate a login system of a different php script with vbulletin? meaning that users who login to the other script, can login to vbulletin too without having to re-register to vbulletin.

thanks
Reply With Quote
  #15  
Old 05-22-2007, 09:38 AM
byon byon is offline
 
Join Date: Apr 2007
Posts: 23
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by apn3a View Post
does anyone have any idea how to integrate a login system of a different php script with vbulletin? meaning that users who login to the other script, can login to vbulletin too without having to re-register to vbulletin.

thanks
these are the stuffs u need.

login.php
PHP Code:
$includes = Array(
        
'config.php');
foreach(
$includes as $include)
        require_once(
$include);
require_once(
DIR '/includes/functions_login.php');


// redirect if user is logged-on
if (!empty($vbulletin->userinfo['userid'])) {
        
header('Location: ' CTRLER);
}

if (
$_POST['do'] == 'login') {
        
$redirectLoginSuccess "http://byon/~john/store/main.php";
        
$vbulletin->input->clean_array_gpc('p', array(
                
'username'        => TYPE_STR,
                
'password'        => TYPE_STR,
                
'md5password'     => TYPE_STR,
                
'md5password_utf' => TYPE_STR,
                
'postvars'                 => TYPE_STR,
                
'cookieuser'               => TYPE_BOOL,
                
'logintype'                => TYPE_STR,
                
'cssprefs'                 => TYPE_STR,
        ));


        
// can the user login?
        
$strikes verify_strike_status($vbulletin->GPC['username']);

        if (
$vbulletin->GPC['username'] == '')
        {
                eval(
standard_error(fetch_error('badlogin'$vbulletin->options['bburl'], $vbulletin->session->vars['sessionurl'], $strikes)));
        }

        
// make sure our user info stays as whoever we were (for example, we might be logged in via cookies already)
        
$original_userinfo $vbulletin->userinfo;

        if (!
verify_authentication($vbulletin->GPC['username'], $vbulletin->GPC['password'], $vbulletin->GPC['md5password'], $vbulletin->GPC['md5password_utf'], $vbulletin->GPC['cookieuser'], true))
        {
                (
$hook vBulletinHook::fetch_hook('login_failure')) ? eval($hook) : false;

                
// check password
                
exec_strike_user($vbulletin->userinfo['username']);

                if (
$vbulletin->GPC['logintype'] === 'cplogin' OR $vbulletin->GPC['logintype'] === 'modcplogin')
                {
                        
// log this error if attempting to access the control panel
                        
require_once(DIR '/includes/functions_log_error.php');
                        
log_vbulletin_error($vbulletin->GPC['username'], 'security');
                }
                
$vbulletin->userinfo $original_userinfo;

                if (
$vbulletin->options['usestrikesystem'])
                {
                        eval(
standard_error(fetch_error('badlogin_strikes'$vbulletin->options['bburl'], $vbulletin->session->vars['sessionurl'], $strikes)));
                }
                else
                {
                        eval(
standard_error(fetch_error('badlogin'$vbulletin->options['bburl'], $vbulletin->session->vars['sessionurl'])));
                }
        }

        
exec_unstrike_user($vbulletin->GPC['username']);

        
// create new session
        
process_new_login($vbulletin->GPC['logintype'], $vbulletin->GPC['cookieuser'], $vbulletin->GPC['cssprefs']);
        
// do redirect
        
do_login_redirect();
}
?>

<!--
here lies the input boxes (username,password)
--> 

config.php

PHP Code:
define('THIS_SCRIPT''storeconfig');
chdir("../vbb/");
include(
"./includes/config.php");
include(
"./global.php"); 
Regards,
John Goh
Reply With Quote
  #16  
Old 09-25-2007, 09:40 AM
xRenegade85 xRenegade85 is offline
 
Join Date: Apr 2007
Posts: 7
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

i was trying to do this to login:
http://mysite.com/login.php?vb_login..._password=blah
but this doesnt do anything, anyone know why?
Reply With Quote
  #17  
Old 10-28-2007, 10:19 PM
version2's Avatar
version2 version2 is offline
 
Join Date: Feb 2003
Location: Philly
Posts: 136
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by xRenegade85 View Post
i was trying to do this to login:
http://mysite.com/login.php?vb_login..._password=blah
but this doesnt do anything, anyone know why?
You are going to pass your passwords in the URL? That's not a good idea.
Reply With Quote
  #18  
Old 01-31-2008, 03:46 PM
nizu nizu is offline
 
Join Date: Jan 2008
Posts: 2
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

i search for it for a very long time! thanks orbita!

now....did anyone try it on vbulletin 3.7?
Reply With Quote
  #19  
Old 12-11-2008, 11:11 PM
Submerge Submerge is offline
 
Join Date: Jan 2006
Posts: 29
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by nizu View Post
i search for it for a very long time! thanks orbita!

now....did anyone try it on vbulletin 3.7?
I'll try it, anyone know of any other articles explaining this technique?

[edit] Nvm, I'm not using two separate user databases
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 01:41 AM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.10194 seconds
  • Memory Usage 2,340KB
  • Queries Executed 23 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (2)bbcode_php
  • (5)bbcode_quote
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)modsystem_article
  • (1)navbar
  • (4)navbar_link
  • (120)option
  • (1)pagenav
  • (1)pagenav_curpage
  • (1)pagenav_pagelink
  • (9)post_thanks_box
  • (9)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (9)post_thanks_postbit_info
  • (8)postbit
  • (9)postbit_onlinestatus
  • (9)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • fetch_musername
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • pagenav_page
  • pagenav_complete
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete