Setting a JSON web token from a secondary api as a secure cookie on WordPress

Question

I am trying to use WordPress, installed via Bitnami on Google Cloud Platform, to build a website, but use another system on a different server (server B) to manage users and content. I want to be able to log a user in to my B server, get a JSON web token, and use that to authenticate users in other parts of the site.

I understand that I can keep the JWT secure I by setting it as ‘secure’ and httpOnly’. I also understand that this can only be set on the server if these values are used , so in this case the WordPress server.
I think I should be able to achieve this using a form to collect the login details, some AJAX to submit the form, and a plugin to handle the server side on WordPress, which gets the token, and then sets the token. I am using a buffer to enable setting the token before there is any output, which is a WordPress requirement it seems.

At present I can submit the correct credentials through the WordPress form, make a call to the server using the AJAX below, and it sets the token as a cookie with the correct flags in place.

But, in order to do this I have to stop the ajax by using the incorrect line:

Console.log(‘Stop’);

otherwise it doesn’t set the token. If I leave that out I get an ‘unexpected token N…’ error in the console, which presumably means I’m not setting valid json somewhere. This hasn’t always been the case with what I have tried, but handling the response in AJAX hasn’t worked yet.

And it refreshes the page each time I press submit, which is obviously not the idea. Clearly I am misunderstanding how the conversation between the AJAX and the server works here – specifically how the event status code is supposed to be returned I think.

In the myFile.php I have called the function at the end, otherwise nothing happens. But this also means the function is called every time the page loads; can I prevent that? Should I call the function in the json that I submit from the front end?

Most frustratingly I had a less hopeless version of this a couple of day’s ago, but forgot to save it. It set the cookie without the page refresh, but I still couldn’t get it to return anything I could then use to initiate the next action – although that was probably the easy bit.

The form:

<form id="loginform" name="loginform" method="post">
    <div>
        Email:
        <input type="text" name="email" id="email" />
        Password:
        <input type="password" name="password" id="password" />    
        <input type="submit" name="loginBtn" id="loginBtn" value="Login" />
    </div>
</form>

The AJAX:

<script type="text/javascript">
jQuery(document).ready(function() {
    jQuery('#loginform').submit(function(e) {
        e.preventDefault();
        jQuery.ajax({
            type: "POST",
            url: '/wp-content/plugins/myFolder/myFile.php',
            data: jQuery(this).serialize(),
            console.log('Stop'); //I know this is very wrong!
            success: function(response){
                console.log("Success");
                console.log(response);
                var jsonData = JSON.parse(response);
 
                if (jsonData == 200)
                {
                    alert('Logged In');
                }
                else
                {
                    alert('Not logged in');
                }
           },
           error: function(error){
                console.log("Error");
                console.log(error);
           }
           
       });
     });
});
</script>

And the php, including some commented out previous attempts:

<?php
/**
 * Plugin Name: Test Login
 * Plugin URI: 
 * Description: Test Login
 * Version: 1.0
 * Author: Me
 * Author URI:
 **/
defined( 'ABSPATH' ) or die( 'No access this way' );
add_shortcode('myLogin', 'myLogin');

function getToken()
{  
    ob_start();
    $method  = 'POST';
    $url     = 'https://serverB/authenticate';
    $headers = array(
        'Accept: application/json',
        'Content-Type: application/json'
    );
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($_REQUEST));
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_SSLVERSION, 4);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($curl);
    
    $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);
        
    if ($code == 200) {
        // set response code - 200 OK
        //http_response_code(200);
    
        $response = json_decode($response, true);
        $token = $response["session_token"];
        setcookie("my_token", $token, time() + 3600, COOKIEPATH, COOKIE_DOMAIN, true, true);
        return $token;
    } else {

        //http_response_code(400);
        
        $response = json_decode($response, true);
        $context = $response["error"]["message"];
        $token = null;
        setcookie("my_token", "error", time() - 3600);
        
        //return $token;
        echo $token;
    }
    ob_end_flush();
}

getToken();

?>
0
Marko 4 months 0 Answers 16 views 0

Leave an answer