AJAX and PHP returning bool and string - php

I’ve got an ajax based script that is designed purely to run a php script to authenticate a user. As there is with user authentication, there could be one of two outcomes: either they get authenticated or they don’t.
To signify success or failure back to the page that called it is extremely easy, you just echo ‘success’; or ‘echo ‘failure’` accordingly and have the JS/jQuery script handle it by the response string. (Or at least I think that’s good practise..)
But apart from essentially returning true or false, if it returned false I would also like to give a message back as to why it failed. Did the user exist? Was the password incorrect? Or did the database access go wrong and need to spit out a technical error code. Since we are responding with true or false already, we can’t send back a message alongside with the false statement otherwise it technically isn’t false as there is more data.
Now I have had these ideas, but I feel like there is a better way to do it:
Return an array [true/false, “String to display”] though this seems clunky within the PHP file and also parsing it on the page
Return success when we want to return true, and label anything else as a failure and assume it’s a message for failure
But in all honesty I feel like this whole text response method is bad especially for something like user authentication as it could possibly be spoofed easily(?) so what would the recommended way to achieve something like this?
Thanks in advance!

This is purely opinion based but I think your missing two important concepts when handling communication between two systems such as PHP (server) and Javascript (client).
One, evaluating response codes. If the HTTP response code is 200, it indicates OK, 201 indicates a resource was created (possibly a session), 401 indicates the user is unauthorized. Given this, just by the HTTP response, you should be able to tell if the action succeeded or not.
Two, using JSON or a markup language. You can pass a JSON string to include both the status and the message and parse the JSON string in Javascript.
Example in PHP being:
http_response_code(401);
$response = [
'success' => false,
'message' => 'Password incorrect'
];
echo json_encode($response);

Related

WP_REST_Response vs WP_Error

I'm a bit confused about how errors are handled in Wordpress's REST API. In their examples, they suggest using WP_Error to return errors, but WP_REST_Response has the HTTP status code as a second parameter, which makes it shorter and somewhat cleaner to my taste.
So I'm comparing this way of returning an error:
return new WP_REST_Response(array('error' => 'Error message.'), 400);
With this one:
return new WP_Error('rest_custom_error', 'Error message.', array('status' => 400));
With the first option, I can have just the error text in my response and it's enough for me. So the response would look like so:
{"error":"Error message."}
With the second one it's more detailed:
{"code":"rest_custom_error","message":"Error message.","data":{"status":403}}
But I also need to specify the error code (first parameter), which doesn't give any advantage to my front-end implementation. Other than the syntax, I'm curious about differences in performance, security and future-proof factors.
So is there any reason to prefer one over the other than personal preferences?
I do as follows:
WP_REST_Response // Used when endpoint code runs just fine but needs to
// tell the client about some other downstream error (e.g. 4xx)
WP_Error // Used when endpoint code has an issue and needs to tell you
// it didn't compute or couldn't find resources etc (e.g. 5xx)
As far as I can tell, WordPress changes the status codes of the responses in unpredictable ways. This is dumb. For instance, if you create a WP_REST_RESPONSE with status 400, it actually sends it as status 200 with "status:400" as data in the body.
What I do:
Just use PHP response functions:
http_response_code(400);
exit;
If you tell me I'm wrong, please explain the benefit of using these two function wrappers. I see the benefit if you work for Automattic and are creating regressions in core itself. If you're a plugin or theme dev, [and you're assuming core works] these functions should be avoided as having no use.

Correct way to return value in API if there is no result

I am making an API for mobile APP based on PHP backend. I have cases where i return an array list and if there is no results i return a message
where results are found:
{"status":"success",
"data":[{"users_details":[{"user_id":1,"parent_id":2}]}],
"token":"success"}
where are no results found:
{"status":"error","data":"no user found","token":"success"}
Is this a good approach, If no what should it be?
i prefer to utilise the http response code so for data not found you can return 204 and when you find matches return 200 and the list of the users
It's a good idea to return a message, that no user data is found, but it would be perfect, if along with the response, a correct response code would be returned. In this case it would be 404 - not found. See https://en.wikipedia.org/wiki/List_of_HTTP_status_codes for more info
It depends on how you process it, I would simply do this.
{"status":"error","msg":"no user found","token":"success"}
Because you don't need to get confused with user data and error message.
consider like if the status is an error then it should have detailed error message in msg key
so you can eliminate the response before the going into actual user data parsing functions. like
if($response['status'] === 'error')
return "Error Message: " . $status['msg'];
I personally stand with empty array. It's normal situation, when API search return no results (and empty array is naturally no results answer). It's okay status for me.
The request may me malformed or there may be problems with database, this is really the case to return status: error.
More to say, when we return in first case array with data and in second string, it is bad approach anyway, cause we have to handle different types of data, it's anti-pattern as I might say. The type should always be the same.
We first check that status is okay or error (no connection, bad connection, bad request etc), then we either check data (empty array = no results) or check error message
{"status": "error", "message": "connection error"}
{"status": "success", "data": []}
{"status": "error", "data": ["First result", "Second result"]}
It doesn't mean that we cannot redirect user to 404 page f.e. if we get such API result, of course. But as for API request, when empty result is normal outcome it shouldn't be treated as error, or we will be mixing real errors with logic, which is obviously bad.

datatable authentication for server side scripting

I am using jQuerydatables and server side scripting with php and mysql. I have modified the script found here:
https://legacy.datatables.net/examples/data_sources/server_side.html
and I have included an if-else which is wrapped around the entire script.
The goal is to only allow results to be returned if the user posted a valid token from my db.
So I have that bit set up. But I am unsure how to handle the error message to the user.
Right now, when a user passes in an invalid token, my website (using datatables) throws up the error invalid JSON response.
I assume this because it is expecting iTotalRecords etc in the JSON returned.
I am wondering if anyone knows how to achieve this. I haven't been able to find any examples.
Algorithm:
if (postedToken exists in db){
return datatables JSON
}
else{
return json in such a way that I can provide an alert to the user that their session has expired
}
and datatable initialisation:
"sAjaxSource": "mydatatablescript.php?token=<?php echo $token;?>
EDIT:
I was returning a valid JSON but I was missing a few parameters which must be required i.e. 'iTotalRecords' => 0, 'iTotalDisplayRecords' => 0, 'aaData' => [], 'sEcho' => 0.
Now I am not getting the error message described in the question. I see there is a "fnDrawCallback" parameter I can include in the datatable initialisation. I suspect here I can check my message param and alert if necessary but I just don't know how to access the JSON from within that function?
As you have seen already, you need to return valid json in any case if your client-side is expecting that.
You could do that using for example something like:
if (postedToken exists in db){
return datatables JSON
}
else{
return json_encode(array('success': false, 'message': 'session has expired'));
}
You should probably add these same keys / parameters when the call is successful as well so that you can easily check in your javascript function what the result of the operation is.

How does get_headers work in the background

I tryied searching for this and I belive I alredy know the answer but it's crusal that I'm not wrong, so here I go..
When calling get_headers, will I retrieve the whole file even though the function only returns the headers or will it retrieve, as expected, only the headers and nothing else?
I'm guessing the last but if I'm wrong this will cause some serious problems..
Also I noticed that there is a global setting I can change to send a HEAD request instead of the default GET request, witch is why I'm asking my self whats really going on.
Edit
Maybe this function is a better alternative? stream_get_meta_data or do they actually do the same thing?
You could also take a look at the source code, if you are familiar with C.
The function is defined here. I quickly looked over this, and it seems it is a header-only request, see line 715:
STREAM_ONLY_GET_HEADERS
GET
Requests a representation of the specified resource. Requests using
GET should only retrieve data and should have no other effect. (This
is also true of some other HTTP methods.) The W3C has published
guidance principles on this distinction, saying, "Web application
design should be informed by the above principles, but also by the
relevant limitations."
HEAD
Asks for the response identical to the one that would correspond to a
GET request, but without the response body. This is useful for
retrieving meta-information written in response headers, without
having to transport the entire content.
Wikipedia/Hypertext_Transfer_Protocol
The PHP-docs clearly states that normal get_headers() uses a GET-request, but you can force it to use HEAD instead, like this:
<?php
// By default get_headers uses a GET request to fetch the headers. If you
// want to send a HEAD request instead, you can do so using a stream context:
stream_context_set_default(
array(
'http' => array(
'method' => 'HEAD'
)
)
);
$headers = get_headers('http://example.com');
?>
Unfortunaley you're right, just read the PHP manual:
get_headers() returns an array with the headers sent by the server in response to a HTTP request.
Also take a look at the examples.
Okay, next time I should spend more attention to the question formulation.
Yeh, if the request type is set to GET (standard) you will get the whole content. You could change it to HEAD, but this is not what you want.

My client queries my server. If the response is negative (e.g. error) how should I communicate it?

Should I rely on http status codes? Or should I use some kind of special response?
My server is running PHP and producing simple JSON responses.
I'd personally say you should do both! Return an appropriate 4xx/5xx status code to show something went wrong and include a message into your JSON response.
E.g. for a successful request:
{
"success": "true"
}
And for fail (e.g. 405 Method not allowed):
{
"success": "false",
"message": "Requested data not available"
}
It could be better if , you can go with an Entity with Two Properties as : Status & Message.
You inherit your query result entity from the above entity.
If the operation is successful then Set the Status to True else set Status to False and set appropriate error message into the Message property of above entity.
Remember that it is better you don't put exact database errors into the client side displays. That may increase the chances of hacking attacks, instead you can log the exact message on the server so that the concerned people can check the messages, if something goes wrong.
So, if Status=True then only the client can further process the message (like accessing the properties or displaying them etc.), else if Status=False, then the error text set at the data access logic, into the Message property will be displayed.

Categories