3

On my site i have one form for client to submit their WordPress site details. On that form containing these fields WordPress admin url, username, and password. I want to check their login details are valid before submitting the form. How i do that?

If there any way to do by using WordPress REST API?

If anyone know please help me Thanks !

  • without customisation, the REST API doesn't permit to test the password. then if you want to test it, you can send it at wp-login.php. – mmm Apr 17 '18 at 12:44
  • @mmm how i do that? Do you have any idea about this? – developerme Apr 17 '18 at 12:46
  • you can try with wp_remote_post – mmm Apr 17 '18 at 13:19
  • According to stackoverflow.com/questions/13679001/… you can test a remote login – Clemens Tolboom Apr 21 '18 at 6:41
  • 1
    This sounds like you're trying to do something you shouldn't. You could easily build a brute-force attack using your application. What is the usage scenario for your request? – Ciprian Apr 25 '18 at 14:02
3
+25

Getting user names and passwords is a horrible idea I hope no user will actually agree to, but beyond that your idea to do it from JS is going to fail due to CORS, which means you will have to do it in AJAX to your server, and let your server try to login, which in turn will most likely flag it as a brute force attacker in no time, and all the major security players will just automatically block the requests.

You need to redesign you software to not need user name and password, probably use something like oauth2 instead. If oauth2 is not applicable for your situation.... well, tough luck.

  • Thank you for your response. Regarding my site i get the username and password form clients and some of the details are working for me some time user given details are not correct so that i need to email him again to get user name password. That is why i am thinking How i check the user given details are correct on that form. they are giving me username,password and admin url. with these details there is any way to check that user given details are correct. – developerme Apr 26 '18 at 13:53
  • it is very insecure to give user name and password anywhere anytime as it is a prime target for phishing attack. Regardless of why you are doing it, no one should be willing to share such information on the web. – Mark Kaplun Apr 26 '18 at 14:01
  • 1
    ... if we are talking about wordpress sites, they should just add a user for your email, and let you reset the password for it. – Mark Kaplun Apr 26 '18 at 14:05
  • Yes i am talking about wordpress site. I getting client username and password via website that is why i asking this question here. – developerme Apr 27 '18 at 5:01
1

First off: there are many reasons why the following code could fail. There is no way to have a system that works everywhere. This is due to various security plugins introducing many different concepts.

Having said that, this code worked for a plain installation as well as one with Wordfence (with not super strict settings) enabled.


wp_remote_post() is the key function in this function. It allows you to send POST requests to remote hosts - which is exactly what you want if you want to check a login.

function WPSE_test_remote_login($url, $username, $password) {
    // remove trailing slash if it exists
    $base = rtrim($url, '/');

    // login url
    $url = $base . '/wp-login.php';

    $args = [
        // the inputs that get POSTed
        'body' => [
            'log' => $username,
            'pwd' => $password,
            'wp-submit' => 'Submit',
            'redirect_to' => $base . '/wp-admin/',
            'testcookie' => 1,
        ],
    ];

    // make the actual request
    $response = wp_remote_post($url, $args);

    // only one cookie? then failed login
    if ( ! is_array($response['headers']['set-cookie'])) {
        return false;
    }

    // if a cookie that contains wordpress_logged_in is set
    // the login was successful
    foreach ($response['headers']['set-cookie'] as $cookie) {
        if (stripos($cookie, 'wordpress_logged_in') !== FALSE) {
            return true;
        }
    }

    return false;
}

I tried this in my local environment, you can get the necessary fields that are usually sent if you access the wp-login.php in your browser.

Then I checked the $result and compared the difference between correct and wrong password. For a failed login, $response['headers']['set-cookie'] looked like this

string(45) "wordpress_test_cookie=WP+Cookie+check; path=/"

or this

array(3) {
  [0]=>
  string(128) "__cfduid=df131...; expires=Sun, 21-Apr-19 12:35:00 GMT; path=/; domain=.example.com; HttpOnly"
  [1]=>
  string(100) "wfvt_144...=5ad...; expires=Sat, 21-Apr-2018 13:05:00 GMT; Max-Age=1800; path=/; HttpOnly"
  [2]=>
  string(74) "wordpress_test_cookie=WP+Cookie+check; path=/; domain=.example.com; secure"
}

However, a successful login returned these cookies

array(4) {
  [0]=>
  string(45) "wordpress_test_cookie=WP+Cookie+check; path=/"
  [1]=>
  string(209) "wordpress_852...=test%7C15...; path=/wp-content/plugins; HttpOnly"
  [2]=>
  string(199) "wordpress_852...=test%7C15...; path=/wp-admin; HttpOnly"
  [3]=>
  string(201) "wordpress_logged_in_852...=test%7C15...; path=/; HttpOnly"
}

We see that wordpress_test_cookie will always get set. However, wordpress_logged_in_852... was only set for successful logins. So we can determine that if this exists, the credentials are correct.

  • Well... There are two problems with that solution, I guess. One is that name of cookie can change, so you can't assume it will be always "wordpress_logged_in_852". Second problem is that you not only check if user data is correct, but also log this user in... – Krzysiek Dróżdż Apr 24 '18 at 13:40
  • @KrzysiekDróżdż For a software that keeps being developed on, your first argument is always true. Even the name of the wp_enqueue_scripts hook can change. Your second point I agree with and didn't really consider when writing the answer. AFAIK there is no other way to check credentials against a remote site – kero Apr 24 '18 at 17:13
  • of course it is. That’s why it’s always better to use developer API and not such workarounds, I guess :) – Krzysiek Dróżdż Apr 25 '18 at 4:53
  • Thank you for your response. Regarding my site i get the username and password form clients and some of the details are working for me some time user given details are not correct so that i need to email him again to get user name password. That is why i am thinking How i check the user given details are correct on that form. they are giving me username,password and admin url. with these details there is any way to check that user given details are correct. – developerme Apr 26 '18 at 13:53
0

There is no way to achieve this without any custom API routes. But of course, you can register such route (or use AJAX instead), if you can edit theme or install plugins on that site.

So, let's do this with REST API...

function my_register_api_hooks() {
    register_rest_route(
        'my_namespace', '/check-login/',
        array(
            'methods'  => 'POST',
            'callback' => 'my_api_check_login_callback',
        )
    );
}
add_action( 'rest_api_init', 'my_register_api_hooks' );

function my_api_check_login_callback($request){
    $user = wp_authenticate_username_password(null, $request['username'], $request['password']);

    if ( is_wp_error($user) ) {
        return array('error' => $user, 'user' => false);
    }

    return array('error' => false, 'user' => $user->ID);
}

When you'll send a POST request to http://example.com/wp-json/my_namespace/check-login/ containing username and password, you`ll get JSON like this:

{
"error": false,
"user": 1
}

where 1 is the ID of user found for given credentials, or

{
"error": ..., <- this will contain error messages
"user": false
}

You have to be aware that this code only checks if user credentials are correct. It will not log user in.

And what if you have no control over site you want to check?

Then there is no way to register your own routes and there's no way to use REST to check user credentials. But... You can use XMLRPC...

One way will be using this library: WordPress XML-RPC PHP Client. It will do the job for you almost all the way or you can use native WP_HTTP_IXR_Client class.

You can use wp.getUsersBlogs method for checking if given credentials are correct.

  • Problem with this is, that OP wants to check a remote/client site - if the site owner has to install a custom plugin first, they could just register them an account – kero Apr 25 '18 at 10:10
  • 1
    @kero "On my site i have one form..." I don't see anywhere in the question info saying that the form is sent to some remote site... But... if so, then he should provide some plugin or use xmlrpc authentication. And certainly he should NOT base on wp-login.php... But, I would strongly advice not to put your WP credentials on some remote site - never ;) – Krzysiek Dróżdż Apr 25 '18 at 10:14
  • I understood the question that OP may be a plugin developer. And before someone sends their credentials so s/he does support their, s/he wants to check their validity. I agree that this is a bad idea, also since the form is probably sent unencrypted via mail – kero Apr 25 '18 at 10:41
  • 1
    @kero and still, OP could do anything with these credentials ;) Regarding the problem - well, that might be the case, I guess... – Krzysiek Dróżdż Apr 25 '18 at 10:43
  • Thank you for your response. Regarding my site i get the username and password form clients and some of the details are working for me some time user given details are not correct so that i need to email him again to get user name password. That is why i am thinking How i check the user given details are correct on that form. they are giving me username,password and admin url. with these details there is any way to check that user given details are correct. – developerme Apr 26 '18 at 13:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.