最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin0浏览0评论

UPDATE THREE

Since I am getting the correct responses from my own api, can I modify the responses I am getting. In the console I see this:

{readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
abort: ƒ (a)
always: ƒ ()
complete: ƒ ()
done: ƒ ()
error: ƒ ()
fail: ƒ ()
getAllResponseHeaders: ƒ ()
getResponseHeader: ƒ (a)
overrideMimeType: ƒ (a)
pipe: ƒ ()
progress: ƒ ()
promise: ƒ (a)
readyState: 4
responseText: "{"success":true}
↵<!DOCTYPE html>
↵<html lang="en-"
setRequestHeader: ƒ (a,b)
state: ƒ ()
status: 404
statusCode: ƒ (a)
arguments: null
caller: null
length: 1
name: "statusCode"
prototype: {constructor: ƒ}
__proto__: ƒ ()
[[FunctionLocation]]: jquery.js?ver=1.12.4-wp:4
[[Scopes]]: Scopes[3]
statusText: "Not Found"
success: ƒ ()
then: ƒ ()
__proto__: Object

I tried using status_header(); in my php but that didn't work.

UPDATE TWO

Is the problem related to this:

If so, I'm not sure I know what to do...

UPDATE

If I use just test_login_file.php as the AJAX url I can include these lines again:

defined( 'ABSPATH' ) or die( 'No access this way' );
add_shortcode('myLogin', 'myLogin');

and remove the ridiculous:

aCompletelyUnlikelyfunction();

In that case the cookie is set, the page doesn't refresh (good so far...), but I get a 404 not found error for the url in the console. This response includes the expected {"success": true} JSON, but also a mass of HTML for a 404 page, so the AJAX response handling doesn't work - which I obviously need to do something else.

Clearly this must be the 'ABSPATH', otherwise it would throw an error as it did previously.

What the heck is going on? Is this a WordPress issue, or am I fundamentally not understanding something?

Thanks for looking!


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.

The code below works and sets a secure, httpOnly cookie with the value of my token.

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

aCompletelyUnlikelyfunction();

otherwise it doesn’t set the cookie (possibly because the AJAX causes some output?). This also cause the page to refresh.

If I remove this line, the AJAX works correctly, giving me the appropriate pop up depending on what I submit. But as pointed out above, it doesn't set the cookie.

I had to comment out these lines to get the AJAX to work:

//defined( 'ABSPATH' ) or die( 'No access this way' );
//add_shortcode('myLogin', 'myLogin');

The form:

html
      <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="hidden" name="call" id="call" value="1"/>
            <input type="submit" name="loginBtn" id="loginBtn" value="Login" />
         </div>
      </form>

The jQuery:

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

And the php:

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

function get_token()
{  
    ob_start();
    $method  = 'POST';
    $url     = 'https:my_B_server/session';
    $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) {
        
        /*if (isset($_COOKIE["my_token"]))
        {
        echo json_encode(array(
        "success" => 'Logged In'
        ));
        }
        else*/
        //{
        $response = json_decode($response, true);
        $token    = $response["session_token"];
        $expiry   = strtotime('+1 month');
        setcookie("my_token", $token, $expiry, COOKIEPATH, COOKIE_DOMAIN, true, true);
        $thing = json_encode(array(
            "success" => true
        ));
        //}
    } else {
        
        $response = json_decode($response, true);
        $context  = $response["error"]["message"];
        $token    = null;
        setcookie("my_token", "error", time() - 3600);
        
        $thing = json_encode(array(
            "error" => $context
        ));
    }
    echo $thing;
    ob_end_flush();
}
if (isset($_POST['call'])) {
    $pmp = $_POST['call']; {
        if ($pmp == 1) {
            get_token();
        }
    }
}

UPDATE THREE

Since I am getting the correct responses from my own api, can I modify the responses I am getting. In the console I see this:

{readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
abort: ƒ (a)
always: ƒ ()
complete: ƒ ()
done: ƒ ()
error: ƒ ()
fail: ƒ ()
getAllResponseHeaders: ƒ ()
getResponseHeader: ƒ (a)
overrideMimeType: ƒ (a)
pipe: ƒ ()
progress: ƒ ()
promise: ƒ (a)
readyState: 4
responseText: "{"success":true}
↵<!DOCTYPE html>
↵<html lang="en-"
setRequestHeader: ƒ (a,b)
state: ƒ ()
status: 404
statusCode: ƒ (a)
arguments: null
caller: null
length: 1
name: "statusCode"
prototype: {constructor: ƒ}
__proto__: ƒ ()
[[FunctionLocation]]: jquery.js?ver=1.12.4-wp:4
[[Scopes]]: Scopes[3]
statusText: "Not Found"
success: ƒ ()
then: ƒ ()
__proto__: Object

I tried using status_header(); in my php but that didn't work.

UPDATE TWO

Is the problem related to this: https://stackoverflow/questions/3445270/jquery-ajax-returning-404-error-but-correct-response

If so, I'm not sure I know what to do...

UPDATE

If I use just test_login_file.php as the AJAX url I can include these lines again:

defined( 'ABSPATH' ) or die( 'No access this way' );
add_shortcode('myLogin', 'myLogin');

and remove the ridiculous:

aCompletelyUnlikelyfunction();

In that case the cookie is set, the page doesn't refresh (good so far...), but I get a 404 not found error for the url in the console. This response includes the expected {"success": true} JSON, but also a mass of HTML for a 404 page, so the AJAX response handling doesn't work - which I obviously need to do something else.

Clearly this must be the 'ABSPATH', otherwise it would throw an error as it did previously.

What the heck is going on? Is this a WordPress issue, or am I fundamentally not understanding something?

Thanks for looking!


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.

The code below works and sets a secure, httpOnly cookie with the value of my token.

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

aCompletelyUnlikelyfunction();

otherwise it doesn’t set the cookie (possibly because the AJAX causes some output?). This also cause the page to refresh.

If I remove this line, the AJAX works correctly, giving me the appropriate pop up depending on what I submit. But as pointed out above, it doesn't set the cookie.

I had to comment out these lines to get the AJAX to work:

//defined( 'ABSPATH' ) or die( 'No access this way' );
//add_shortcode('myLogin', 'myLogin');

The form:

html
      <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="hidden" name="call" id="call" value="1"/>
            <input type="submit" name="loginBtn" id="loginBtn" value="Login" />
         </div>
      </form>

The jQuery:

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

And the php:

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

function get_token()
{  
    ob_start();
    $method  = 'POST';
    $url     = 'https:my_B_server/session';
    $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) {
        
        /*if (isset($_COOKIE["my_token"]))
        {
        echo json_encode(array(
        "success" => 'Logged In'
        ));
        }
        else*/
        //{
        $response = json_decode($response, true);
        $token    = $response["session_token"];
        $expiry   = strtotime('+1 month');
        setcookie("my_token", $token, $expiry, COOKIEPATH, COOKIE_DOMAIN, true, true);
        $thing = json_encode(array(
            "success" => true
        ));
        //}
    } else {
        
        $response = json_decode($response, true);
        $context  = $response["error"]["message"];
        $token    = null;
        setcookie("my_token", "error", time() - 3600);
        
        $thing = json_encode(array(
            "error" => $context
        ));
    }
    echo $thing;
    ob_end_flush();
}
if (isset($_POST['call'])) {
    $pmp = $_POST['call']; {
        if ($pmp == 1) {
            get_token();
        }
    }
}
Share Improve this question edited Oct 4, 2020 at 8:15 Marko asked Sep 28, 2020 at 12:44 MarkoMarko 115 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Seems odd to answer my own question, but in case it is of use to someone, this is the answer.

To make an ajax call to a plugin, and receive the response correctly you must register that endpoint with the plugin. This allows you to sidestep the protection Wordpress is putting in your way. I'm not sure if links to YouTube are allowed/accepted on here, but there is an excellent video here. I will remove if this is considered bad practice.

php for plugin

add_action ( 'rest_api_init', 'add_callback_url_endpoint' );

function add_callback_url_endpoint(){
    register_rest_route(
    'my_route/',
    'receive_callback',
     array(
       'methods' => 'POST',
       'callback' => 'my_receive_callback'
        )
     );
  }


function my_receive_callback($request_data){
    $data = array();
    $params = $request_data -> get_params();
    $index = $params['index'];

if(isset($index)){
        $data = array(
'index' => $index,
'status' => 'OK'
);    
}else{
            $data = array(
'status' => 'Not OK'
}
   return $data;
}
发布评论

评论列表(0)

  1. 暂无评论