9. June 2011
von Blackbam
Recently I was confronted with the problem to have multiple user types on a WordPress Blog who needed to be logged in using an external service/authentication mechanism partly. But they all had to use the same login form for the system. A common problem? The WordPress Function Reference and  Codex do not document this topic very well and it took me a lot of time to figure out how to do this best, so I want to keep it for the future and provide it to my blog visitors.  

Override the WordPress default login action

  Write the following to your functions.php-file:
// this action is executed just before the invocation of the WordPress authentication process
add_action('wp_authenticate','checkTheUserAuthentication');

function checkTheUserAuthentication() {

     $username=$_POST['log'];
     $password=$_POST['pwd'];

    // try to log into the external service or database with username and password
    $ext_auth = try2AuthenticateExternalService($username,$password);

    // if external authentication was successful
    if($ext_auth) {

         // find a way to get the user id
         $user_id = username_exists($username);
         // userdata will contain all information about the user
         $userdata = get_userdata($user_id);
         $user = set_current_user($user_id,$username);

         // this will actually make the user authenticated as soon as the cookie is in the browser
         wp_set_auth_cookie($user_id);
         // the wp_login action is used by a lot of plugins, just decide if you need it
        do_action('wp_login',$userdata->ID);

        // you can redirect the authenticated user to the "logged-in-page", define('MY_PROFILE_PAGE',1); f.e. first
        header("Location:".get_page_link(MY_PROFILE_PAGE));
    }

}
    Note that this script will login your useres totally without using their passwords, so use it carefully.   If you experience any problems with this way of authentication, make sure that the Cookies in the Browser are set and sent properly - make sure that setcookie() in wp-includes/pluggable.php uses all parameters of the setcookie()-function correctly. Especially check the values for COOKIE_DOMAIN, COOKIEPATH and SITECOOKIEPATH as we had and issue with that.  
Share

Dieser Eintrag wurde am 9. June 2011 um 22:22 in der Kategorie WordPress, WP Scripts veröffentlicht. You can book the comments for this article RSS 2.0. Feedback, discussion, commendation and critics are welcome: Write a comment or trackback.


Tags: , , , , , ,

Warning: Use of undefined constant Ext_related_links - assumed 'Ext_related_links' (this will throw an Error in a future version of PHP) in /home/.sites/609/site1266/web/blackbams-blog/wp-content/themes/SilentWoodsByBlackbam/single.php on line 75

Already 27 comments belonging to "WordPress custom external authentication login/logout PHP script":

Kommentare abonnieren (RSS) or URL Trackback

Cedric     says:

on 19. July 2011 at 20:35 on clock


Check this out: http://www.cedricve.me/blog/2011/07/18/how-to-make-use-of-wordpress-passwords/ It explains how you can make an external login with the credentials of a wordpress installation. I hope this can help you ;)

Blackbam     says:

on 20. July 2011 at 18:44 on clock


Hey Cedric, thank for sharing this article about external authentication.

However your article is about logging in WordPress users into a custom session from a page outside the WordPress installation using the Username and Password of the WordPress installation. In spite of that, this article is about logging in users into WordPress using an external login mechanism (like the Username and Passwords of a huge company database) without using the WordPress Username and Password.

I hope the difference between the to lines of action is clear!

Ryan Wheale   says:

on 26. January 2012 at 03:31 on clock


I don't understand why you would use "username_exists" and "get_userdata" if your information exists in an external database. It seems like you would just get null values. Can you elaborate? Thanks.

Blackbam     says:

on 28. January 2012 at 18:41 on clock


This script is for undergoing the WordPress login mechanism by logging in users without knowing their actual password. If the external authentification was successful $ext_auth is true and you do not have to know any WordPress password (and therefore you do not have to synchronize or even KNOW any passwords).

The users must still exist in the WordPress database though, because WordPress will not work correctly otherwise. But you can simulate this, by writing a new user with the desired user name into the database (function: wp_create_user), if a user loggs in for the first time.

A possible use case for this is a SSO (Single Sign on) system, where you might and should not know the passwords of your users.

Is it clear now?

Ben Lobaugh     says:

on 23. February 2012 at 04:00 on clock


Thanks for posting this. This info is stupidly hard to find. Just as a point of clarification, after you are doing the external check to see if the user is valid externally you should probably be doing another check to see if they exist in the WP DB and if not create them first right? If I am understanding what I read correctly an id for the user has to be setup already? I think with your example I will be able to get my auth plugin almost up and running :)

Blackbam     says:

on 26. February 2012 at 22:56 on clock


1. Do the external check: The external login must be successful and the return value must be validated. If a remote request to another service is needed, use the http://codex.wordpress.org/HTTP_API">WordPress HTTP API. --> Yes

2. Doing another check to see if they exist in the WP DB and if not create them first right ---> Yes

3. EVERY user in WordPress has a unique ID, so we use this ID to identify a user in this script (Note: http://codex.wordpress.org/images/9/9e/WP3.0-ERD.png">WP Users Table). If the ID is found, our user is automatically logged in.

4. If the user NOT exists, there are two possibilities.

First possibility - The users are should be created automatically:
if($ext_auth && !username_exists($username)) {
    // create new user
   wp_create_user($username,$password,$email);
}
Add this code after this line: "$user_id = username_exists($username);". But notice, that wordpress NEEDS an user email. Username and email could be the same. If users are authenticated only using the external servers, you can generate a random password.

Second possibility - The users must register to the WordPress powered site seperatly, but still authenticate via the external service. If this possibility is chosen, do something like:
header("Location:".get_page_link(REGISTER_PAGE));
Hopefully things are easy to understand now. Maybe you can post a link to your new auth plugin here?

Ben Lobaugh     says:

on 26. February 2012 at 23:17 on clock


Thanks, I appreciate the help. I am writing a mini tutorial on this also. I will send a pingback to this page.

AndyD   says:

on 28. January 2013 at 01:35 on clock


Hi I found this site whilst trying to source a tutorial describing how to build a login/logout mechanism fr a simeple web site - our child's playgroup is seeking such a method so that parents can log in and see photos of their children at outings, and their artwork. Could you recommend somewhere to find this sort of info please? Thanks in advance, and apologies as it is not relevant to your blog.

Blackbam     says:

on 28. January 2013 at 01:55 on clock


Hello, unfortunatly I do not know what you mean by this exactly. This script is for purposes of extending login functions for WordPress manually, I think you should search for some Plugin in the WordPress Plugin repository to satisfy your needs.

Z. Zhou   says:

on 26. April 2013 at 21:11 on clock


Hi, thank you very much for posting the scripts. I am designing a plugin that allows our users across multiple Wordpress sites to login with with their CAS credentials. I understand what you are trying to do but have a few questions. I appreciate it very much if you could take the time to answer.

1. How do you handle new user registration, forget / reset password, and update email requests?
2. Are you synchronizing your Wordpress user db with the external login user db?
3. What are the pros and cons you think for replacing Wordpress login with external login (like you did) versus linking external login to the native Wordpress account? The former method you use is likely to have problem #1, while the latter method will have problem #2.

Blackbam     says:

on 27. April 2013 at 11:34 on clock


Hello.

1) I think that there is not an general answer how to do that. You could just forward you users to some external registration site. Another possibility is to use the API of the external service and build a custom registration page for WordPress. The same is true for forget/reset passwords. For synchronizing data you also may have to integrate the API of an external service.

2) In the project I was using this script, I was exactly doing that. When the user is logging in for the first time, the WordPress user is created. It depends on your needs how you handle this. Are ONLY users with external authentication allowed? May the WordPress account exist longer than the external account? Depending on your needs you should use the external service API, some Cronjob for synchronizing data or nothing of that.

3) This also strongly depends on your project. Sometimes you do not have the choice, when the customer requires you to use "Single Sign on" for its software system. If you do have the choice, you should make a decision in favor of your users: Which one will be more comfortable for them? If it does not matter, I guess, I would use the one which is easier to implement.

Z. Zhou   says:

on 15. May 2013 at 01:28 on clock


Thanks a lot Blackbam! Your answers will be very helpful!

Bruce   says:

on 03. July 2013 at 01:21 on clock


My question. I'm not a programmer so please forgive my inadequacy. This solution looks promising, but I'm not sure it is what I need. What I am trying to do is to pass 2 custom fields (encrypted username and password-generated from another application) and imported into a membership plugin database. The goal is single sign on. This plugin has the ability to sync the member users to the Wordpress db, so when they sign in through Wordpress they are signed into the membership or when they sign into the membership they are signed into Wordpress. I am planning to import the logins (with the encrypted username and passwords) into the member db. Then I will sync them together, but here's the rub.

I'm not sure which angle to take, but what I want to do is pass the 2 custom encrypted name and user fields out to the application through a query, when they login like: http://mysite.com/Default.aspx?js=[Enter Encrypted UserID here]&pe=[Enter Encrypted Password here].

I would have something like this imported:

UserID: Demo1
Password: Demopass1123
Member level: AB
ID: 2 –( ID to determine if AB or CD)
Email: * (email if they have it)
Encrypted UserID: O8Nwr2YieNkB
Encrypted Password: iBNxoePkWFU0LDUrTV/J3gC=


Does this make any sense? We have already created the users in the application with their encrypted logins and that works fine, but I am at a loss how to make the Wordpress connection. Any thoughts are greatly appreciated.

Blackbam     says:

on 03. July 2013 at 10:55 on clock


At first I will clarify what this script does:

1. Imagine you have to websites, website A is a non-wordpress site containing a user database and website B is a WordPress website
2. Users of website A should be able to log-in at website B using their username/password of website A
3. Preconditions: Website A must define some API / Webservice to validate user credentials
4. Website B uses the script from above - it sends a message to website A, website A validates username and password and sends back an answer (this answer could contain somehting like allow / deny or in case of the success the whole user data)
NOTE: The messaging for "try2AuthenticateExternalService" and exact procedure for this is not shown in the script
5. Website B checks the answer of website A: If it is positive, the user is logged in (single sign on) to both services (be sure that all auth-cookies are set correctly)
6. Optionally: Save users on their first login to the WordPress database and synchronize them (would not definitly recommend this, as you have some kind of "duplicate content" - however if website A fails, existing users can still log into website B)


Now to your question:
1. I think it is possible what you want to do: If somebody tries to login to WordPress, send username and password to the external application
2. Your external application must have an interface which returns the user information when you have sent username and passwort
3. Import whatever you want into your users db

The process in detail can be different from application to application. I recommend you to do some research on Single-Sign-On on the internet.

Hope this is of any help.

Bruce   says:

on 03. July 2013 at 20:11 on clock


Thanks for your clarity. I assume that my issue strictly revolves around the external service authentication. Basically I just want to import already created username and password (encryptions) into a database (Wordpress would not work for this natively since it hashes those anyway), and then pass those two fields to the external application (the query as illustrated). Then when someone signs into the Wordpress side of the fence. it automatically sends those 2 encrypted fields to the query. I have the membership application that can import those custom fields, and it does have an API where I can use a GET or POST http function. I am just not sure how to send the request to the external query from the database or the API itself. If I am unclear about this, it's just my pure lack of understanding how to program via php.

Blackbam     says:

on 03. July 2013 at 20:43 on clock


Hmm first of all, if you want to use the same passwords, the following article may be useful for your purpose: http://www.cedricve.me/2011/07/18/how-to-make-use-of-wordpress-passwords/. Using this mechanism could simplify your problem.

The second thing is, that you probably do not know exactly how to make remot requests with PHP? Maybe the PHP-CURL library is what you need (http://stackoverflow.com/questions/7460577/php-remote-function-call-and-returning-the-result ).

Hope this helps.

Al   says:

on 29. November 2013 at 06:09 on clock


Auto Login to Wordpress site - maintains cookie and session (persistent) This does the job nicely: http://wordpress.org/plugins/autologin-links/ * Do not try to use CURL to do this as that's on the server side cannot pass cookies to the browser client.

John Denis     says:

on 13. February 2014 at 21:18 on clock


Great post. You should use wp_set_current_user instead of "set_current_user" which was deprecated in version 3.0

Nilima   says:

on 24. February 2014 at 11:31 on clock


Hi, Thanks for this short code for external authentication. We are dealing with the same scenario. We want to avoid any changes to the codebase, so thinking of making a plugin. We think changes to the codebase will affect the new updates for WP. Is that true? Will your solution work in a plugin. Let me know. Thanks for the solution !

Blackbam     says:

on 24. February 2014 at 15:02 on clock


@John: Thank you for this hint I will check this.

@Nilima: First of all, yes, you should NEVER hack the core of WordPress (changing the codebase). Furthermore this solution WILL work in any Plugin or even in your functions.php-file of your WordPress theme (at least as long as they keep the wp_authenticate action hook - hope they will do so). You should get some knowledge about the WordPress Action Reference and the WordPress Filter Reference so that you can understand how this works.

Creatives Infotech     says:

on 26. February 2014 at 15:49 on clock


Excelent thought, U can also try wp-admin third authentication field here <a href="http://www.creativesinfotech.com/blog/adding-extra-authentication-field-wordpress-wp-admin-login-page/">Creatives Infotech

Shimul   says:

on 21. April 2014 at 07:37 on clock


Hi Blackbam,

Thanks for your efforts. I want to use this in facebook login. When user takes the first attempt to connect facebook, I check is username or email exist or not. If not I register them with a random generated password. But in later after their logged out and next attempt to login, I want user should be logged by facebook credential. In my case I want to login by username and email or facebook identifier. Please could you help me how to do this using your code. I added you code in my if else condition but does not work. It works only functions.php without condition.

Please help me.
Sihmul

Blackbam     says:

on 21. April 2014 at 19:44 on clock


Hi Shimul

suppose there are a lot of Plugins for WordPress to use Facebook login, so you should not have to implement these in a custom way as described in this post. This is what you usually need in order to implement a single authentication system for big projects or whatever. Anyway, if you want to use this code you have to adjust it to your needs. It is just a skeleton, an idea how to start.

Hope this helps you anyway.

Cheiff   says:

on 03. June 2014 at 00:44 on clock


Thanks a lot! very useful!

Mike Doubintchik   says:

on 25. July 2014 at 00:00 on clock


Blackbam,

Is it possible to create a script that has the following parameters:

1) User goes to built-in WP login screen
2) Upon submitting credentials, the script checks if user exists in the WP database. If yes, user is logged in.
3) If no, the script checks if the user exists in the external database. If yes, the user is logged in.
4) Also, permissions from the external database would need to be mapped to custom user roles/groups.
Thanks, Mike

Mahesh Lalwani   says:

on 03. September 2014 at 19:21 on clock


Hi Blackbam, In my wordpress project I am have created template page where user can register. Now Problem I am facing is making user logged in after registration. I have created a user and after that I have tried make the user log in using below code same as you mentioned above.

wp_set_current_user( $user->ID, $user->user_login );
wp_set_auth_cookie($user->ID,true);
do_action( 'wp_login', $user->user_login, $user );

I have also created a log in template to allow user loged in by using same above code but same issues occurs. Now problem I am facing is as soon as I moved to new page, I found user is not logged in.. Please help

Blackbam     says:

on 03. October 2014 at 17:01 on clock


@Mike: Yes, this is possible. However I will not provide the code for you here, you have to figure it out your own ;-)

@Mahesh: There are different possibilities to login a user directly from. Sorry but I cannot provide free code debugging on this page. Check your cookies and client-server communication and you may probably find the problem.

Leave a comment: