Problem parsing the body of a POST request - php

So what I'm trying to do is: with a link similar to: http://localhost/API-REST/Endpoints/ajoutDeMessage.php?contenu='Hello'&idUser=4. For now, I'm only testing my request with Postman. So I'm putting this URL directly in Postman, and press send.
When I'm doing a request without a body, it works fine.
So, I need to send a string and an id through the URL, and with a function, I'm inserting these data in my database.
With the php://input, I expect to have the variables contenu and idUser in the body for a SQL request.
What I want to do next is a React app which will communicate with the API (but that's not related for now).
So here is my code:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
require_once('../Configuration/database.php');
require_once('../Users/messages.php');
$database = new Database();
$db = $database->getConnection();
$json = json_decode(file_get_contents("php://input"),true);
var_dump($json);
if(!empty($json->contenu) && !empty($json->idUser)){
$contenu = strip_tags($json->contenu);
$idUser = strip_tags($json->idUser);
$message = new Messages($db);
if ($message->addMessage($contenu,$idUser)){
http_response_code(201);
$response['message'] = 'GOOD ENTRY';
}else{
http_response_code(400);
$response['message'] = 'BAD ENTRY';
}
}else{
http_response_code(400);
$response['message'] = 'INCOMPREHENSIBLE DATA';
}
echo json_encode($response);
} else {
http_response_code(405);
$response['error_code'] = 405;
$response['message'] = 'BAD REQUEST TYPE';
echo json_encode($response);
}

There is no post body
i'm putting this url directly in postman, and press send.
I don't use postman myself, but doing this will generate a post request with no data it's the equivalent of:
curl -X POST http://example.com
That's not passing a post body at all. The intent is more like:
curl http://example.com
-H 'Content-Type: application/json'
-d '{"contenu":"Hello","idUser":4}'
This is why file_get_contents("php://input") doesn't return anything.
Note that html form data is available via $_POST - but only for urlencoded POST bodies (which I understand not to be the intent of the question).
Where is the data?
i'm putting this url directly in postman, and press send.
Returning to this quote, the only place for the data is in the url - that is not the normal way to pass data with a post request.
Url arguments are available via $_GET, with the url in the question this code:
<?php
var_dump($_GET);
will output:
array(2) {
["contenu"]=>
string(7) "'Hello'"
["idUser"]=>
string(1) "4"
}
A detail, but note the string includes the single quotes which are in the url (that are probably not desired).
What's the right way to do this?
With a request being made like this:
curl http://example.com
-H 'Content-Type: application/json'
-d '{"contenu":"Hello","idUser":4}'
That data can be accessed like so:
<?php
$body = file_get_contents('php://input');
$data = json_decode($body, true);
$jsonError = json_last_error();
if ($jsonError) {
print_r(['input' => $body, 'error' => json_last_error_msg()]);
exit;
}
echo $data['contenu']; // Hello
echo $data['idUser']; // 4
...
This is very similar to the code in the question, the error appears to primarily be how the request is being made rather than the php logic.

Related

How to receive and store CURL username with PHP

I have the command:
curl -k -u **username:password** --request POST -H "Content-Type:application/json" -d "{\"name\":\"John\",\"age\":\"31\",\"test\":\"New York\"}" http://siteteste.com/receive.php
I want to get the server-side username and password with PHP.
I am using the POST method.
My PHP:
<?php
// Only allow POST requests
***// I want the username and password here with PHP POST.***
***$user = $_POST[""]; // Not working :(***
if (strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') {
throw new Exception('Only POST requests are allowed');
}
// Make sure Content-Type is application/json
$content_type = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '';
if (stripos($content_type, 'application/json') === false) {
throw new Exception('Content-Type must be application/json');
}
// Read the input stream
$body = file_get_contents("php://input");
// Decode the JSON object
$object = json_decode($body, true);
// Throw an exception if decoding failed
if (!is_array($object)) {
throw new Exception('Failed to decode JSON object');
}
// Display the object
$getit = $object['test'];
print $getit;
How can I do it?
I try, but not working.
I search StackOverflow and others site, but not found informatio
Your body is json-encoded.
You will get your data here:
$body = file_get_contents("php://input");
// Decode the JSON object
$object = json_decode($body, true);
var_dump($object); // <-- do this to view your data.
The -u option you are using is used for authentication. For example for http-authentication.
In case you want to add data, you have to modify your -d parameter. For example, here i added a user:
-d "{\"name\":\"John\",\"age\":\"31\",\"test\":\"New York\",\"user\":\"test-user\"}"
Or in the other case you really want the http-authentication-data use:
$_SERVER['PHP_AUTH_USER']
$_SERVER['PHP_AUTH_PW']

Slack Events PHP Response

I'm working on an integration between Slack and Filemaker utilizing PHP. I am successful in having the code create a record in Filemaker based on the json request, and also have no trouble returning the challenge key to Slack.
However, I'm having trouble passing the header response 200 OK to Slack, while passing the challenge back. It looks like it has to be one or the other.
I've tried to move the HTTP header to different areas in the code, but haven't had any success so far.
Here is the current code:
<?php
$data = json_decode(file_get_contents('php://input'), true);
if (!isset($data["challenge"])) {
$body = $_SERVER['HTTP_X_SLACK_RETRY_REASON'];
require_once ('Filemaker.php');
//$body = file_get_contents('php://input');
$fm = new Filemaker();
$fm->setProperty('database', '');
$fm->setProperty('username', '');
$fm->setProperty('password', '');
$command = $fm->newPerformScriptCommand('PHP_RESPONSE', 'script', $body);
$result = $command->execute();
}
else {
header("Content-Type: text/plain");
header('X-PHP-Response-Code: 200', true, 200);
echo $data["challenge"];
}
?>
The result I expect is for the code to return the challenge code for Slack, while also returning an HTTP header of 200 OK.
Currently I can see I am receiving an error of "http_error" from Slack, which is what leads me to believe the problem is that the header is not being passed back successfully.
Any ideas on what is wrong, or suggestions on the right direction to proceed would be greatly appreciated.
The problem was occurring because for events slack doesn't send "challenge" as a parameter when sending events. It looks like echoing "challenge" is only needed when initially setting the URL for the events API.
I enclosed the challenge echo in a if statement that would only trigger if the challenge variable was present. After doing so the 200 OK was successfully passed.
Here is the code I used that solved the problem for me:
$data = json_decode(file_get_contents('php://input'), true);
if (isset($data["challenge"])) {
$message = [
"challenge" => $data["challenge"]
];
header('Content-Type: application/json');
echo json_encode($message);
}
The documentation is actually a bit inconsistent on this topic. It claims you can respond the challenge in plan text, but the example shows it as x-www-form-urlencoded.
To be on the safe side try returning the challenge as JSON. That works perfectly for me. You also do not need to explicitly set the HTTP 200 code.
Example code:
$message = [
"challenge" => $data["challenge"]
];
header('content-type: application/json');
echo json_encode($message);

Setting correct content type for cURL to receive a response

I'm trying to create a relatively simple PHP endpoint for users to send requests to. I know that the endpoint is working because when I accessed it using cURL the parameters I sent to my database we're added. The problem however is that when I use
var_dump($response);
The page returns "NULL".
So the code is working fine, I just want to know how to print an error/success message
This is what I've tried so far on the endpoint
header("HTTP/1.1 200 OK");
header('Content-Type: text/plain');
echo 'Success message';
the full cURL code:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
CURLOPT_POSTFIELDS => 'example=this'
);
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
$response = json_decode($resp, true);
var_dump($response);
So how can I get the success message to properly show instead of "NULL"?
Test if your curl code returns something by testing: var_dump($resp). It looks like NULL comes from json_decode. You are not returning valid JSON from the endpoint.
php > var_dump(json_decode("Success message", true));
NULL
Try returning a json string such as:
php > echo json_encode("Success", true);
"Success"
Note the " around it. This encodes a json string. See the JSON spec for a reference on how to encode json. Best practice, if your return json, then run your content through json_encode().
Your curl code seems correct.

Facebook Messenger API - Can't verify webhook URL (PHP)

I'm trying to set up a fb messenger chatbot but don't seem to be able to get the webhook callback url verified. Every time I try to verify it I get this error message - The URL couldn't be validated. Response does not match challenge, expected value = '1596214014', received=''
Here's the screenshot:
Screenshot
Here's the php I'm using -
<?php
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'token_my_token') {
echo $challenge;
}
I've also tried
echo $_GET['hub_challenge'];
and just
echo file_get_contents('php://input');
All of these result in the same error message as above. Basically, as far as I can tell facebook isn't sending a GET request to my server or if it is it doesn't include any data. Can anyone tell if I am doing something wrong or if there is a setting I need to change to ensure facebook is sending the data correctly?
Edit - When checking the access logs this is what I find, which looks like facebook isn't sending any data in the get request.
2a03:2880:1010:dffb:face:b00c:0:8000 - - [19/Apr/2016:20:50:06 +0000] "GET /wp-content/plugins/applications/fbmessenger.php HTTP/1.0" 200 - "-" "facebookplatform/1.0 (+http://developers.facebook.com)
Thanks
just try my code and it's gonna work.
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'Your's app token') {
echo $challenge;
}
//Token of app
$row = "Token";
$input = json_decode(file_get_contents('php://input'), true);
//Receive user
$sender = $input['entry'][0]['messaging'][0]['sender']['id'];
//User's message
$message = $input['entry'][0]['messaging'][0]['message']['text'];
//Where the bot will send message
$url = 'https://graph.facebook.com/v2.6/me/messages?access_token='.$row;
$ch = curl_init($url);
//Answer to the message adds 1
if($message)
{
$jsonData = '{
"recipient":{
"id":"'.$sender.'"
},
"message":{
"text":"'.$message. ' 1' .'"
}
}';
};
$json_enc = $jsonData;
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_enc);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
if(!empty($input['entry'][0]['messaging'][0]['message'])){
$result = curl_exec($ch);
}
you have to return Challenges so Facebook can verify its correct Url and Token Match
<?php
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'token_my_token') {
echo $challenge;
}
Facebook Docs Link ( In Node.js ) You can see challenge return after verifying the token
https://developers.facebook.com/docs/messenger-platform/getting-started/webhook-setup
Could you try my API? https://github.com/Fritak/messenger-platform
If you set it like in example, it should work:
// This is just an example, this method of getting request is not safe!
$stream = file_get_contents("php://input");
$request = empty($stream)? $_REQUEST : $stream;
$bot = new \fritak\MessengerPlatform(
['accessToken' => 'token_for_app',
'webhookToken' => 'my_secret_token',
'facebookApiUrl' => 'https://graph.facebook.com/v2.6/me/' //2.6 is minimum
], $request);
if($bot->checkSubscribe())
{
print $bot->request->getChallenge();
exit;
}
If not, problem is somewhere between Facebook and script, not in PHP itself. Go check apache settings etc.
Well issue might be on facebook side, they had some issues over past few days...
Have only this code in your php file: (fbmessenger.php)
<?php
// header('HTTP/1.1 200 OK');
/* GET ALL VARIABLES GET & POST */
foreach ($_REQUEST AS $key => $value){
$message .= "$key => $value ($_SERVER[REQUEST_METHOD])\n";
}
$input = file_get_contents("php://input");
$array = print_r(json_decode($input, true), true);
file_put_contents('fbmessenger.txt', $message.$array."\nREQUEST_METHOD: $_SERVER[REQUEST_METHOD]\n----- Request Date: ".date("d.m.Y H:i:s")." IP: $_SERVER[REMOTE_ADDR] -----\n\n", FILE_APPEND);
echo $_REQUEST['hub_challenge'];
You will have requests saved in a file called "fbmessenger.txt" in the same directory.
Note that for some strange reason you may need to submit few times to
get it approved & saved! (I had to hit "save" 8-9 times before fb
approved link)
Make sure you use https (SSL) connection and once your connection is done, verify your token with "hub_verify_token" to make sure request is coming from fb.

PUT request with json content-type

I have a switch based on $_SERVER['REQUEST_METHOD'] and something is going wrong in the PUT case.
The plausible way to read PUT is to use php://input and read it with fopen or file_get_contents.
The data that gets sent to PUT is of Content-type: application/json
Currently, this is the case I have got:
case "PUT":
parse_str(file_get_contents("php://input"), $putData);
var_dump($putData);
if(isset($_GET['id'])){
putData($_GET['id'], $putData);
} else {
print json_encode(["message" => "Missing parameter `id`."]);
http_response_code(400);
}
break;
The great thing is that my cURL request with key/value pairs work perfectly fine. The data gets filled and my putData() handles everything just fine.
The problem is that I need to accept JSON in this case, how do I go about?
My REST client throws an empty array when I var_dump($putData).
Try using json_decode instead of parse_str
case "PUT":
$rawInput = file_get_contents("php://input");
$putData = json_decode($rawInput);
if (is_null($putData)) {
http_response_code(400);
print json_encode(["message" => "Couldn't decode submission", "invalid_json_input" => $rawInput]);
} else {
if(isset($_GET['id'])){
putData($_GET['id'], $putData);
} else {
http_response_code(400);
print json_encode(["message" => "Missing parameter `id`."]);
}
}
break;
Just guessing here, but if your REST client accepts JSON for this request, it will choke on var_dump() which outputs a string which isn't JSON right back onto the response. Try removing var_dump()
Also, I'm pretty sure you must call http_response_code() before any output is sent to the client.

Categories