miniBB ® 

miniBB

®
Simplicity has never been more powerful
 
miniBB Home Home miniBB Community Forum and Bulletin BoardForums miniBB Forums Demo - Full Mode with Add-onsDemo The Gallery of miniBB Arts and Design LayoutsGallery of Arts miniBB Forums Worldwide ShowcaseShowcase miniBB Forum Software FeaturesFeatures miniBB Forum Script RequirementsRequirements Installation and Maintenance manual for your miniBB ForumManual
Forum Program and Plug-ins - Download for Free!Download Auto-CompilerCompiler Paid Extensions and Add-ons for your miniBB ForumPaid Extensions Paid Support for CustomersPaid Support miniBB Commercial License and Attribution Link RemovalLicense Contact UsContacts

miniBB synchronizing with the existing membership

By Paul Puzyrev, author of miniBB

Notice: description below is prepared only for the coders familiar with PHP. If you are not familiar with PHP and do not know much about web programming and coding, this article IS NOT FOR YOU. If you have read this solution, and tried it, and still something is not working on your side - we can't investigate it for free, because each system has its own specifics which we may not even know about, and this requires a lot of time to work on. miniBB authors are providing only paid support on synchronizing miniBB with a specific software. The same applies to project owners who have not enough time to go deeply into this solution, but need to synchronize your PHP software with miniBB as soon as possible. Contact us privately to get in touch.

Synopsis

This article describes the following:

How the principle of the online authorization works

Not depending on the type of the software, the language its written on or other terms, the basic principle of the web authorization is similar in almost all cases:

  1. In a browser, you enter your username and password on the login form, they are passed to the validation script, which some way connects to the members database on the server, compares the entered data, and gives TRUE or FALSE on output, meaning authorization was successful or failed.
  2. If TRUE is given, the program needs some way to keep member's data on the client side, which means a browser. Meaning this data was set, it may be later re-compared each time when user opens some section of the site, or just knowing it is set, the program will think you are "authorized" and keep you logged in. This data is stored in a cookie, a little file which is kept on your computer under browser's folder or registry.
  3. Each cookie always consists of the following parameters:
    • Name: a unique cookie identifier which is recommended to consist only of the alphanumerical characters and possible underscore sign ("_"), and it should begin with a letter;
    • Domain: the domain name which cookie should be recognized from; for example it may be www.cookiedomain.com (meaning it will work only for 'www' domain) or .cookiedomain.com (meaning it will work from any sub-domain as well). Note that for cookies, the domain without 'www' and with 'www' are different cases. If Cookie may be read only from the same domain it is set; if you type http://cookiedomain.com, the cookie will not be read from http://www.cookiedomain.com;
    • Path: this defines from which folder of the domain cookie will be available to read; for example '/' (means it is available for all folders and sub-folders of the domain) or '/members/' (means it will be set and read only from the forums folder, at the same time it may be operated from the 'top' level as well, i.e. from the main folder - but if cookie was set for the root folder, it can't be operated from the sub-folder);
    • Value: a comparision value which the authorization script may use when identifying you;
    • Expiration time: defines when the cookie will expire; if 0 is passed, it means the cookie is expired at the end of browser's session, i.e. until the browser is closed;
    • Secured connection flag: if authorization is executed via SSL (i.e. if you see 'https' not 'http' in URL bar), it needs to be specially noticed via this flag. This is a rare thing and you won't probably even need it to study.

Let's take a look at the following schema:

Online authorization

As you see, we can call Cookie "part of the browser", "Comparison script" is part of the server, and since the Browser and a Server interact, that way we can save user's input and either enable or disable members-only functions for him.

Since the cookie is stored in the "clear" format on your computer and may be theoretically stolen, it is recommended to keep the Value of the Cookie in encoded format. This means even if you steal the cookie and know its Value, it doesn't mean you can log-in with this data, since it doesn't contain username and password in unencoded strings. That way the "good" authorization process works.

How PHP session works

There were many questions on our forums regarding how difficult is to use sessions instead of cookies and how this affects security. Basically, PHP session means a cookie itself. Named usually 'PHPSESSID', this cookie contains a randomly generated session ID which is kept on the Server. This ID is associated on the Server with the special array of session data which may contain almost anything, incl. username, password, member ID and other information. For keeping user's authorization, it is usually needed only to open a PHP session and put authorized data under it with the built-in PHP session functions. This session always expires when you close the browser, that is the main difference between it and a "classic" cookie which may be kept for the specified amount of time. It is impossible to steal user's information from a PHP session (it is stored on the Server), but still, it's possible to recognize a user by session ID which is stored both on the Server and in the Browser.

How miniBB's authorization works

If we take the above graph, "Comparison script" will stand for miniBB itself, specially, the files named bb_cookie.php and bb_func_login.php.

bb_func_login.php works only with the initial user's input, i.e. when the username and password are entered on the login form and passed for validation. This file is core-destructive, it means modifying this file you destroy possibility of the easy miniBB upgrade in the future, because if this file will be included in updates list, you will need to re-apply your changes again. In miniBB project, we always follow the non-core-destructive solutions, that means applying a solution, you still keep the possibility of the easy core files upgrade, but keeping all of your custom changes, incl. custom authorization mechanism.

Here we have a non-core file named bb_cookie.php, which means you are allowed to edit it without limitations and difficult upgrades fear. It contains cookie-processing functions as one for setting the cookie (setMyCookie), for deleting the cookie (deleteMyCookie), for getting the Value of the cookie (getMyCookie), encoding the password for storing in database (writeUserPwd), and the main function which compares user's cookie/input with database information (user_logged_in).

Taking into attention written above, let's explore some details:

  1. you enter username and password on forums, they are passed through a login form containing variable called $mode. As soon it is set the script supposes the user is logging in, and calls bb_func_login.php;
  2. there we crypt the password which you have entered with the function writeUserPwd (which by default is just a conversion to MD5 string), and then compare username and encoded password by the values which are stored in database (or as for admin account, they are compared by what is stored under setup_options.php file). miniBB crypts all passwords kept in database with the same writeUserPwd function, that's why we can safely store and compare only crypted values;
  3. if the login is passed, a miniBB cookie is set, which Value consists of the string in the following format: UNAME|PASSWD|EXPTIME; where 'UNAME' stands for non-encoded Username, 'PASSWD' means the password hash encoded by default in MD5, 'EXPTIME' is for cookie's expiration timestamp.
  4. in the future the script will read this cookie everytime when you open any forum page or section, using getMyCookie and user_logged_in functions, i.e. parsing the Cookie's Value and comparing it to what is stored in database.

The most important thing to know here is that user is authorized in miniBB if his ID is not equal to 0. In the scripts user ID is always associated with the $user_id variable. It is set under bb_func_login.php (for example when you post and login simultaneously) or user_logged_in function.

Is storing passwords in MD5 format safe?

It is not even safe to drive by a car, what can we say about MD5? In theory, it can be hacked and broken, but only for really weak passwords, which consist of a sensful word or very simple phrase. As more your password is difficult-to-guess as less it's possible to decrypt it from MD5. In hacking practice, it is only possible using "brute force attack" which may take few lifes. Keeping miniBB forums for years, we still have our passwords safe, because they are strong. That's why the forums were still not broken. We still have read that somebody broke the forums, where the admin's password was... 'admin'. It's sad and funny at once. Of course there is no responsibility for such cases.

On another hand, forums are not the payment gateway and they do not contain any kind of serious private information. Even if somebody gets your password, he can't do anything except posting under your nickname or optionally delete few of your own messages. Even if somebody steals your admin password, it is always possible to restore forums from a backup. Another words, when working on miniBB authorization, we didn't invent anything difficult, like it is done recently for other similar software. This keeps the things transparent and still strong, if you know how to make them strong.

You can rewrite miniBB's writeUserPwd using another encoding algorithm here, let's say SH1 (thus changing password's length in database). That will keep the things more secured and still simple. This function is described below.

miniBB compatibility with the 3rd party software

Few programmers are going wrong way trying to store user's information in TWO database tables, one of them belongs to the website authorization, and the other belongs to forums. For example, when user registers on the main page, his data is duplicated to the forums table as well; however it's definitely a wrong approach, 'cause in that case it won't be possible to achieve the user is logged on forums automatically when he's logged on the site. Users will just enter the same data for the main website and forums, but it won't make their live easier at all.

Synchronizing miniBB means there will be only ONE membership records table, and this table will belong exclusively to the main software. I.e. users are allowed to register and modify the profile only from the main software; forums will just READ this information, but not to create or update it. It means you can log-in from the main site, and you will appear logged in on forums; moreso - in some cases it's even possible to achieve that if you are logged-in from forums, you will be logged in from the main website automatically. That's the main sense of the best synchronization.

When it comes to synchronizing miniBB and other software, the most important question is: how to let your own script think that user is logged in from miniBB, and how to let miniBB think that user was logged in from your main website? Take a look at the picture above again: important are just Cookie and Comparison script.

If you know what kind of format your cookie has, and how to "emulate" it with miniBB, you've got the half-work done. Further, you need to build a Comparison script, i.e. rewrite miniBB's bb_cookie.php functions, so they are connecting to the existing users table, not default miniBB's table, and comparing user's input based on this table.

As about the Cookie information, Mozilla Firefox browser provides some excellent tools. Go to "Tools" - "Options" - "Privacy" - "Show cookies". It will list all cookies available for the Browser. Locate your domain, and under it you may see a specific Cookie by name. Cookie explores with the all necessary information mentioned above: Name, Value (Content), Expiration date, Path and Host (Domain). Analyzing this information, you may understand how the 3rd party program sets the login Cookie, and repeat it similarly in miniBB, rewriting some functions.

But first of all, you should know in advance, is miniBB compatible with the software you are going to synchronize it with? miniBB will be compatible only if:

  • forum tables and members table which belongs to your software, are in the SAME mySQL database (it is VERY critical - the solution is NOT possible if you run two different databases for forums and the main website - you need to achieve that both forums and website tables are under the same database);
  • in the existing membership table, each user has an ID, and this ID is a unique numerical auto incremental field;
  • if there is no user with ID=1, it should be possible to add this user manually without affecting the current database and scripts (it will identify miniBB's admin);
  • it should be possible to add new, miniBB-related fields to the end of your current users table without affecting the current database and scripts;
  • your custom script should not allow users to change their chosen login name, else it will lead to the total mess on forums; but if you are not afraid of it, this becomes not a mandatory condition.

Besides of that, miniBB requires the following fields in users table:

  • user_id* - integer auto_increment type; stores unique user ID.
  • username* - varchar type, stores user's login (sign in) name.
  • user_regdate - datetime type, sign up date.
  • password* - varchar type, stores encrypted user's password (in miniBB, it is encrypted via MD5() function).
  • user_email* - varchar type, stores unique email of the user.
  • activity - integer type (0 or 1) - identifies user's access to forums. If this values is set to 0, user's membership is disabled for some reason. 1 by default.
  • user_viewemail - integer type (0 or 1) - if 1, user has allowed to show his email publically. 0 by default.
  • user_sorttopics - integer type (0 or 1) - default sorting by latest replies or latest topics.
  • language - char type, 3 letter index of forums interface language.
  • num_topics - integer type; number of topics user created.
  • num_posts - integer type; number of posts user created.

Fields marked with asterisk above most probably will exist in almost every members table. Other fields must be added to the end of the table manually. Fields may have different names, which can be re-defined under miniBB's setup_options.php - $dbUserShema setting. I'll explain it more carefully below.

Example of pre-existing membership

Below we will take a very simple example of user's authorization on the site which you can repeat on your own side and see how it works, creating files and pasting codes. I hope this example will be pretty straightforward to understand how to implement all this for your own script ;-)

Let's say we have an existing users table which can be created with the following SQL statement:

And here, we will insert few test records to this table:

Under main website, we have 3 scripts: first is an index file which contains a login form, second is the Comparison script which parses user login data and sets the Cookie (PHP session), and the third is kind of members-only area. Below are the codes for these scripts:

Login form (my_index.php):

Comparison script (my_auth.php):

Members-only area (my_members.php):

Try to re-create all written above on your main website, then try to login as 'Paul' with the easy-to-guess password 'xyz123' (easy-to-guess is still good for testing purposes only). I hope you can analyze these scripts as well and conclude that the authorization script compares user's input by what is stored in database. If such username/password combination is not found, it just redirects to the login form; if it's found, it starts a session and stores $_SESSION's array variables like 'auth' and 'ID', meaning this uses is successfully logged in. Later this is also compared when you enter 'members-only' area.

Now besides our 'main' script, let's install miniBB, for example, under subfolder 'forums' comparing to the root folder. Check miniBB manual for installation if you are not sure how to proceed. After installation, log-in to admin panel, create a test forum, and under this forum create some test topic to see everything works. Then under forums folder, put the script my_session.php with the following content:

After you "were logged" from the main my_index.php page in the root folder, point your browser to my_session.php. You should see that a PHP session is available, and it displays the values of 'auth' and 'ID' meaning username of the logged user, and his ID. It means we can read Cookie from forums folder, and you must be sure on it in all other cases. Usually, PHP session is stored for the whole domain with the path '/', that's why we don't have problems referrencing to a session from the sub-folder. In your own script, you always must keep in mind that it must set the domain-wide Cookie.

Now we actually go to the synchronization process itself.

Synchronizing miniBB with the pre-existing membership

  • Set $Tu setting of miniBB's setup_options.php to 'my_users' - letting miniBB know which members table to use;
  • Let miniBB do not accept new registrations - under the same file setup_options.php set $enableNewRegistrations=FALSE;
  • Let miniBB do not allow to use its core for password reminding - just remove bb_func_sendpwd.php file from the forums folder;
  • add missing miniBB fields at the end of the existing members table; in our case the SQL statement will look like following:


    Following miniBB architecture, you can add other related fields as well (for example, 'user_custom...' for installing some of the add-ons like avatars etc.) Learn how to do it at advanced level from the article Adding new profile field to miniBB.
  • Under the same file setup_options.php locate $dbUserShema setting. It contains all miniBB-related member fields in the array format: CONSTANT_NAME => array(NUMERICAL_INDEX, DATABASE_FIELD_NAME, FORM_FIELD_NAME). Leave FORM_FIELD_NAME by default for array's values like username and email; forum-related fields may be specified because it could be allowed to modify forums Profile (I will describe it later below). Numerical index is defined using "Determine fields" tool. Download it, copy under forums folder and point your browser's URL to it. It should display something like this:

    Table fields in table my_users
    ID - 0
    name - 1
    pass - 2
    email - 3
    user_regdate - 4
    activity - 5
    user_viewemail - 6
    user_sorttopics - 7
    language - 8
    num_topics - 9
    num_posts - 10

    Building the logics on the above, set the following:

  • Let miniBB read the existing Cookie first. For this, open two tabs in your browser, one for the main website, one for forums. Log-in from your main page (my_index.php in our example), switch to forums tab and locate my_session.php being sure you can be recognized from the forums folder.

    Now update bb_cookie.php letting it read your cookie's value, i.e. PHP session. First of all, at the very top of file we need to open a session the same way like our website does, putting this somewhere at the top of file:



    Then it comes time to modify getMyCookie function. In default miniBB, this function returns an array of username, MD5-encoded password and expiration date. In our case we don't have the two last things stored in the session, so we will return an array of username and ID (later we will use them in user_logged_in comparison function):



    getMyCookie passes its values to user_logged_in. Analyzing it, you can see that this function may be used in two cases: when the cookie Value is passed from getMyCookie (it is a case when we check user's login status everytime when the forum page is opened), or if it's passed from bb_func_login.php, which builds a default miniBB cookie's Value in the $cook variable upon login process. We may use this variable for getting Username, and then put a simple mySQL request to get an ID. That way we will "fake" miniBB and keep the core at once. In the below code of that function, we may completely eliminate a special routine for admin, because Admin's account is kept in the custom users database anyway. We also can remove code parts which are related to the cookie expiration time and related operations, because in the case of PHP sessions cookie will be deleted as soon as you close the browser. In your custom case, you can eliminate this part as well, specially if your site doesn't "remember" login after you close the browser. Modifying users request condition a bit, we get the most related forum profile fields, and then compare Username and user ID passed to that function. If they are similar, we perform some code to identify admin from a regular user, and finally declare all necessary login status variables:

  • Now open your forums, and if you did everything correctly, you should see the user 'Paul' is logged in on forums, if he's logged in on the main website! Try to log-out on the main page, and log-in as admin, then refresh the forums page. You should see you are logged in as administrator, and the "Admin panel" link appears at the bottom the forums page.
  • If everything of the above mentioned proceeds successfully, it's time to implement cookie's setting process itself. For this we will need to modify setMyCookie function, which is related to bb_func_login.php routine. This function just gets a username, a password, an expiration time and then forms the cookie based on these values setting it in a browser, without returning any value. We need to re-write this function, so it gets user ID as well, and then puts user ID and username under PHP session array - similarly to what is done under my_auth.php:



    In opposite, the function deleteMyCookie should empty the session:



    As for the writeUserPwd function, since our webpage script stores all passwords in clear format in database, we just need to return the same value as we get:

  • If you applied all modifications correctly, try to log-in/log-out on forums, it should completely work. Try to log-in/post message at once for the test topic as well. Try to log-in with the invalid password and see what happens. At this stage you must be sure the authorization fully proceeds on miniBB side.
  • After you have posted a message, click on the "Member" title under the poster's name, it will open user's profile page. In many cases initially it will simply say "User doesn't exist!" which means miniBB tries to build an incorrect mySQL request. Debugging mySQL requests in miniBB is simple: open setup_mysql.php file, locate db_simpleSelect and under it you will find an 'echo' statement which you need to uncomment. Then reload the page and the SQL request will be echo'ed on the screen, this may give you some ideas of what you did wrong.

    In our custom case, everything should work fine by default, except for "registration date" it will display "1 Jan 1970" and it will show email address as well, despite it is forbidden by user under forums profile. Our custom script is not handling registration date (at the time it should), and this is still a mandatory field for miniBB which doesn't handle it as well (remember? we have disabled registrations). So we need just to re-program registration time displaying function to return an empty value.

    In miniBB it's possible to rewrite any profile-related functions putting them under bb_plugins.php file. Study more under Adding new profile field to miniBB article. In our case, we need to take some functions from bb_func_usernfo.php, putting them under bb_plugins.php with a condition to enable them only when viewing user's profile ($action=='userinfo'). Also we must follow users table's field names and rename these functions by the same manner:



    You may rewrite other profile-related functions the same way, keeping in mind if function returns an empty value, it won't be displayed on the profile page at all.
  • The last question in our integration process is handling user's profile form itself. As you may notice, besides personal information this profile contains some forums options, like default sorting of topics, language selection, email privacy. If you think for the users these options will work by default and are not needed to change, just disable profile editing under miniBB (at the same time it should be enabled in your custom script!) - set $enableProfileUpdate=FALSE; under setup_options.php. In some cases, disabling the modifying of the profile may be a mandatory condition. It depends on your own program.

    There is also a way to enable basic forums options under profile, shortening templates/user_dataform.html. There we will need to eliminate all free type text fields except login name (which can't be changed in miniBB), and optionally eliminate admin's editing variable (read below why). Adding hidden email field (with the default email value) and password fields (with empty values) is a mandatory condition, because these fields are the most important for any profile, incl. miniBB. Finally this template may look like this:



    Please note that having a custom system, we do not recommend to edit user profiles by admin like it's available in miniBB (i.e. including { $adminEditField } variable on the form). As admin, you should manage users accounts at your main website level, forgetting that such feature exists on the forums too. However in the case if you have enabled Avatars or Photo album add-ons, it would be necessary to enable basic profile part at least. It may work for the basic profile fields as well, but only in some easy cases. Preventing this from moderators as well, you may put the following code under bb_plugins.php:

Examples package all-in-one

You may download all above mentioned code examples in one package, clicking here. Use in your scripts at your own risk! I've programmed them in 10 minutes without taking security question in mind. They are just examples.

Ending the lecture...

Each software has its own principles of authorization, and here only your professional/educational level matters of how to achieve a good synchronization. It may take hour of work, and it may take days or even a week. In my experience I still didn't meet the software which is technically compatible with miniBB, but still can't be emulated because it has a terrific authorization algorithm which can't be decoded by a human mind. Everything can be integrated if it's compatible. Even if it's not possible to rewrite miniBB functions because 3rd party authorization is TOO strong (for example, it was the case when I synchronized miniBB and the recent version of WordPress), it's still possible to include 3rd party functions and use them in miniBB (you may check my outdated article on synchronizing miniBB and the older version of WordPress).

But complexity is just a private case, because mainly the integrations I did in the past are simple, as the web should be. Entertaining Internet is not a serious thing to worry about complex algorithms, the same miniBB is. Good luck in coding :-) and under our related topic on forums you may post additional questions to this article.

Forum owners about miniBB:
One of the most interesting piece of internet forums to date, its stability and performance is top tier!
as written by...Christian
miniBB ® miniBB.com © 2001-2024. All rights reserved.
miniBB® is a registered trademark.
@ Contact Us 


  ⇑