Laravel setup for basic API and AJAX-calls - json

Laravel POST return type?
I'm setting up an API alpha version using basic auth single sign on.
Cant debug with postman/js because its not returning JSON but redirecting me instead. From what Ive read AJAX calls shouldnt be redirected? Do I have errors in the configuration?
Routes:
Route::post('/test1', 'tradesCtrl#test1']);
//Route::post('/test1', ['middleware' => 'auth.basic.once', 'uses' => 'tradesCtrl#test1']);
AJAX call:
$.post(
"http://localhost:8000/test1",
{
p1:"100a",
p2:80
},
function(data, status,jqXHR){
console.log(data);
});
Controller (this will echo HTTP (!):
public function test1(Request $request)
{
if($request->ajax()) {
echo "AJAX!";
} else {
echo "HTTP!";
}
}
Allow cross domain for now in App.php
// allow origin
header('Access-Control-Allow-Origin: *');
Kernel.php disable csrf protection by commeting out
app\Http\Middleware\VerifyCsrfToken::class
If I try to insert validation for parameters
public function test1(Request $request)
{
$this->validate($request, [
'p1' => 'Integer',
'p2' => 'Integer'
]);
echo "Serving stuff";
}
This immediately return in a 404 page not found when failing validation, probably a redirect to something else that's not working??

Related

Yii2 Stripe Webhook testing: "[ERROR] Failed to Post"

I set up a basic Webhook endpoint in a Yii2 controller just to test the connection:
class CreditCardController extends Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'webhook' => ['post'],
],
],
];
}
public function beforeAction($action)
{
if ($action->id == 'webhook')
$this->enableCsrfValidation = false;
return parent::beforeAction($action);
}
... I just want to dump the payload and return HTTP 200 (roughly based on an example I followed here)
public function actionWebhook()
{
$payload = file_get_contents('php://input');
ob_start();
var_dump($payload);
error_log(ob_get_clean(), 4);
echo json_encode(['status' => 'success']);
}
I installed the Stripe CLI and forwarded the Webhook to my local test server:
stripe listen -f https://testsite.office/credit-card/webhook
When I trigger an event that includes something I am listening for:
stripe trigger invoice.payment_succeeded
I get this message:
[ERROR] Failed to POST: Post "https://testsite.office/credit-card/webhook": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
If I remove the POST rule for the action and code the URL in a browser, it works fine.
Any ideas?
Joe
For anyone slogging along with the same issue (I don't see a lot of Stripe/Yii2 webhook chatter online), here is what worked for me.
I noticed that Yii threw a HeadersAlreadySentException in the Apache error_log. So I had to had to specify the response format as JSON:
return new Response([
'format' => Response::FORMAT_JSON,
'statusCode' => 200,
'statusText' => 'Webhook Handled',
]);
Probably not consequential to this problem, but I also changed accessing the payload to the "Yii way":
$payload = json_decode(Yii::$app->request->getRawBody(), true);

How to read JSON data in laravel controller?

Before this, I was getting 405 methods not allowed error in live server
ajax call to upload files:
$('#form-repeater').on('submit',function(e){
e.preventDefault();
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
let thiss=$(this);
let form = document.getElementById('form-repeater');
let data =new FormData(form);
$.ajax({
type:thiss.attr('method'),
url:thiss.attr('action'),
data:data,
dataType:'JSON',
// ContentType:'application/json',
cache: false,
processData: false,
success:function(response){
if(response.message=='1'){
Swal.fire(
'Product Added Successfully',
'',
'success'
)
setTimeout(function(){
window.location.href="/banner";
}, 2000);//wait 2 seconds
}
else{
error = response.errors;
if(error.staff){
$('#form-repeater .invalid-staff').html(error.staff);
}else{
$('#form-repeater .invalid-staff').html('');
}
if(error.customerNumber){
$('#form-repeater .invalid-cust_numb').html(error.customerNumber);
}else{
$('#form-repeater .invalid-cust_numb').html('');
}}});
This is my response from ajax call:enter image description here
normally I can't retrieve data in my controller:
I debug using dd($request->all());
When sending JSON requests to your application, you may access the JSON data via the input method as long as the Content-Type header of the request is properly set to application/json. You may even use "dot" syntax to dig into JSON arrays: $name = $request->input('user.name');
Then on your controller you could do something like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* Store a new user.
*
* #param Request $request
* #return Response
*/
public function store(Request $request)
{
$name = $request->input('user.name');
// Manage your data the way you want
}
}

Can't authenticate for REST testing

I have the following virtual host name setup on xampp: reporting.dev
public function userIsAuthenticated(\ApiTester $I)
{
$I->amGoingTo('Check Authentication works');
// i've tried both of these ways to authenticate
$I->amHttpAuthenticated('my_email', 'my_password');
$I->haveHttpHeader('Authorization', 'Basic super_long_token');
$I->sendGET(Url::toRoute('/api/reports', true));
$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
$I->deleteHeader('Authorization');
}
The following request works in postman http://reporting.dev/api/reports using a Basic Auth header and the same token in the test above.
This is my api suite config:
class_name: ApiTester
modules:
enabled:
- REST:
depends: PhpBrowser
#url: /api/
part: Json
- Yii2:
part: [orm, fixtures]
configFile: 'config/web.php'
I'm using Yii2, if I remove the behaviors function from my api controller that determines the authentication as Basic Auth, I then do get a 200 response and the expected json.
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::className(),
'except' => [],
];
return $behaviors;
}
So I'm unsure what else I can do here or why I'm not authenticated
The problem I had here was the auth token I have in my DB was not base64 encoded.
public function userIsAuthenticated(\ApiTester $I)
{
$I->amGoingTo('Check Authentication works');
// fixed now
$I->haveHttpHeader('Authorization', 'Basic ' . base64_encode('Basic super_long_db_auth_token'));
$I->sendGET(Url::toRoute('/api/reports', true));
$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
$I->deleteHeader('Authorization');
}

Get json error when calling from angular with zend framework 1

My code in zend action is as follow:
$this->getResponse()
->setHeader('Content-Type', 'application/json');
$result = array("status" => true, "result" => $output);
$json = json_encode($result);
echo $json;
And My angular controller is as follow:
app.controller("statController", function($scope, $http){
$http.get("mydomain/controller/action/")
.success(function(response) {
console.log(response)
}).error(function(response) {
alert(response)
console.log('Error : ' + response);
});
});
When I call the url from the browser and inspect it in the Network tab the result is in json.
But when I inspect it from my angular call, the result has this error:
SyntaxError: JSON.parse: unexpected end of data
Also the url I call (the zend controller and action) is not in the same domain as my angular.js code. I use Zend Framework 1.
UPDATE
I found the prblem. I was trying to access from different domain so I only needed to add
$this->getResponse()->setHeader('Access-Control-Allow-Origin', '*');
To my action.
Try the following code at your action,
public function yourAction()
{
// Disable the layout and view for the action
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender();
// Set the header as JSON
header("Content-Type:application/json");
// Your code starts here
// .........................
$result = array("status" => true, "result" => $output);
$json = json_encode($result);
echo Zend_Json::encode($json);
}
Note: Code is not tested. Try it once, may be its the issue with your layout or something.

Handle json array CAKEPHP

Here's my javascript snipet
<script type="text/javascript">
$(document).ready(function() {
$('form#FormId button.btn').click(function(event){
$.ajax({
type: "POST",
url: "/controller/edit",
data: $("#FormId").serialize(),
success: function(response) {
alert(response.message);
alert(response['message']);
}
});
});
});
Here's my controller action
public function edit() {
$this->autoRender = false; // We don't render a view in this example
$this->request->onlyAllow('ajax'); // No direct access via browser URL
echo json_encode(array('message'=>'Welcome','type'=>'success'));
exit;
}
Both alerts on the javascript are returning "undefined" how to handle?
So nobody is getting this correct.
You need to use the JSON view
See how to enable with this section
class PostsController extends AppController {
public $components = array('RequestHandler');
public function index() {
$this->request->onlyAllow('ajax');
$this->set(array(
'data' => array('message'=>'Welcome','type'=>'success'),
'_serialize' => 'data',
));
}
}
Cake will now automatically set the correct headers, serialize as JSON and not render the layout.
As a side note, your code alert(response.message); does not work beacuse response is a string. your header is text/html not application/json. Try console.log(response) and you will see it is just a string.
I get this to work using the following code in the controller
public function edit()
{
$this->RequestHandler->respondAs('json'); // Very important without this it will not work
$this->autoRender = false;
$data = array('message'=>'Welcome','type'=>'success');
return json_encode($data);
}
try add
dataType: 'json',
to your ajax method.
if it not work, try this:
add
$this->response->type('text/plain');
to your index method.
ie brower did not know json format text.
and what broswer did you used for this test? use F12 open the developer kit to check what the server response, is it a objct
From my experience echoing content doesn't work. You should instead return the json_encoded data.
This will make your edit() function look like this:
public function edit()
{
$this->autoRender = false;
$this->request->onlyAllow('ajax');
return json_encode(array('message' => 'Welcome', 'type' => 'success'));
}
To make sure it works; just alert the whole response object to see what is returned.