Slim Framework: Setting encoding on response - php

I'm having trouble setting the encoding on the response.
Tried:
$app->contentType('text/html; charset=utf-8');
header("Content-Type: application/json");
$app->response()->header('Content-Type', 'application/json;charset=utf-8');
I'm stuck... :-/
EDIT
I've downloaded the Slim/slim-skeleton via Composer.
I need to return JSON in my Route.php:
$app->get('/getStoresByBounds', function () use ($app, $stores) {
$app->contentType('application/json');
$myStores = $stores->getStores();
$app->response()->write(json_encode($myStores));
$app->stop();
});

From The Response/ Headers/ Set Header:
$newResponse = $oldResponse->withHeader('Content-type', 'application/json');

You can try this :)
// APP
$app = Slim::getInstance();
// CONTENT-TYPE
$app->contentType('application/json');
// STATUS
$app->status(200);
// RESPONSE ARRAY
$response = array();
// PRINT THE RESPONSE ARRAY
$app->response()->write(json_encode($response));
$app->stop();
Or try to access $app inside your function by:
$app = \Slim\Slim::getInstance();
Since you are using V3, you might use this:
$app = new \Slim\App();
$app->get('/getStoresByBounds', function (Request $request, Response $response) {
$myStores = $stores->getStores();
$response->getBody()->write(json_encode($myStores));
$newResponse = $response->withHeader(
'Content-type',
'application/json; charset=utf-8'
);
return $newResponse;
});

Related

How to set Content-Type in Slim to XML?

I want to output application/xml as the Content-Type for my Slim Output. Below you see my code which generates the output. All code that is commented out is unfortunately not working to output the corresponding Content-Type. Do you have any suggestions?
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use \Slim\Helper\Set;
require 'vendor/autoload.php';
use Psr7Middlewares\Middleware\TrailingSlash;
$app = AppFactory::create();
$app->get('/{show}/feed', function(Request $request, Response $response, $args) use($app) {
$html = '<?xml version="1.0" encoding="utf-8" ?><sampletag></sampletag>';
// $app->response->headers->set('Content-Type', 'application/xml');
// $response = $response->withHeader('Content-type', 'application/xml');
$response->getBody()->write($html);
// return $response->withStatus(201)->withHeader('Content-Type', 'application/xml')->getBody()->write($html);
return $response;
});
$app->run();
This should work:
$response = $response->withHeader('Content-Type', 'application/xml');
You have commented out the line responsible for adding required headers to the response. The following works fine:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use \Slim\Helper\Set;
require 'vendor/autoload.php';
use Psr7Middlewares\Middleware\TrailingSlash;
$app = AppFactory::create();
$app->get('/{show}/feed', function(Request $request, Response $response, $args) use($app) {
$html = '<?xml version="1.0" encoding="utf-8" ?><sampletag></sampletag>';
// Do not comment out the following line
$response = $response->withHeader('Content-type', 'application/xml');
$response->getBody()->write($html);
return $response;
});
$app->run();

ionic v3 angular v5 cant pass CSRF to php Slim server

I have made PHP Slim server. Authentication for it and CSRF.
I want to use it as a REST Server.
I have a created an App using IonicFramework which uses Angular.
I want to authenticate myself with this code
let hheaders:Headers=new Headers();
hheaders.append('Access-Control-Allow-Origin' , '*');
hheaders.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
hheaders.append('Accept','application/json');
let options = new RequestOptions({ headers:hheaders});
let data = new FormData();
data.append("email", this.myForm.email);
data.append("password", this.myForm.password);
data.append("csrf_name", this.myForm.csrf_name);
data.append("csrf_value", this.myForm.csrf_value);
return this.http.post('http://10.1.3.101:8088/public/auth/signinservice',data,this.options)
.map(res => res.json())
.toPromise();
But I always get Failed CSRF check! I do not know what is the problem. At this point the Slim Server is basic. It is very simple and similar to this Github project with new methods in AuthController.php
like
public function getSignInService($request, $response){
$nameKey = $this->csrf->getTokenNameKey();
$valueKey = $this->csrf->getTokenValueKey();
$name = $request->getAttribute($nameKey);
$value = $request->getAttribute($valueKey);
$tokenArray = [
$nameKey => $name,
$valueKey => $value
];
return $response->write(json_encode($tokenArray));
}
and
public function postSignInService($request, $response, $args){
$auth = $this->auth->attempt(
$request->getParam('email'),
$request->getParam('password')
);
if(!$auth){
$data = array('status' => 'error');
$newResponse = $response->withJson($data, 203);
return $newResponse;
}
$data = array('status' => 'Successful login');
$newResponse = $response->withJson($data, 200);
return $newResponse;
}
and added routes for the methods.
How could i successfully authenticate with Ionic v3 and Angular v5?

Notice: Undefined offset: 0 in C:\wamp64\www\lynda2\src\Chatter\Middleware\Authentication.php on line 12

Hi i'm created a web service with Slim from a course of lynda "Building APIs in PHP Using the Slim Micro Framework" but when i want login, this error Occurs
Notice: Undefined offset: 0 in C:\wamp64\www\lynda2\src\Chatter\Middleware\Authentication.php on line 12
Authentication
namespace Chatter\Middleware;
use Chatter\Models\User;
class Authentication
{
public function __invoke($request, $response, $next)
{
$auth = $request->getHeader('Authorization');
$_apikey = $auth[0];
$apikey = substr($_apikey, strpos($_apikey, ' ') + 1);
$user = new User();
if (!$user->authenticate($apikey)) {
$response->withStatus(401);
return $response;
}
$response = $next($request, $response);
return $response;
}
}
User.php
<pre><code>
namespace Chatter\Models;
class User extends \Illuminate\Database\Eloquent\Model
{
public function authenticate($apikey)
{
$user = User::where('apikey', '=', $apikey)->take(1)->get();
$this->details = $user[0];
return ($user[0]->exists) ? true : false;
}
}
</code></pre>
index.php
<pre><code>
require 'vendor/autoload.php';
include 'bootstrap.php';
use Chatter\Models\Message;
use Chatter\Middleware\Logging as ChatterLogging;
use Chatter\Middleware\Authentication as ChatterAuth;
$app = new \Slim\App();
$app->add(new ChatterAuth());
$app->add(new ChatterLogging());
$app->get('/messages', function ($request, $response, $args) {
$_message = new Message();
$messages = $_message->all();
$payload = [];
foreach($messages as $_msg) {
$payload[$_msg->id] = ['body' => $_msg->body, 'user_id' => $_msg->user_id, 'created_at' => $_msg->created_at];
}
return $response->withStatus(200)->withJson($payload);
});
$app->get('/', function ($request, $response, $args) {
return "This is a catch all route for the root that doesn't do anything useful.";
});
// Run app
$app->run();
</code></pre>
The error is stating that when you "login" there is no Authorization header present.
$request->getHeader('Authorization') returns an empty array, so when you attempting to access the first element of the array, you get your error:
$_apikey = $auth[0]; // Will trigger error, since there are no elements in the array
Thus to aviod this error, get $apikey like this:
public function __invoke($request, $response, $next)
{
$auth = $request->getHeader('Authorization');
$_apikey = array_shift($auth);
if ($_apikey) {
$apikey = substr($_apikey, strpos($_apikey, ' ') + 1);
$user = new User();
if (!$user->authenticate($apikey)) {
return $response->withStatus(401);
} else {
return $next($request, $response);
}
} else {
// Authorization header is missing, therefore unauthorized access
return $response->withStatus(401);
}
}
This is an older thread, but in case anyone else is following this tutorial ... the code the OP posted was supposed to do exactly what it does - to fail if there is no authorization header present.
Looks like the OP missed one step: adding the bearer token to the request. In Postman, go to Authorization > Type > Bearer Token and paste a valid token in the input field. I believe that it was clearly stated in the tutorial. Afterward, everything works as expected.

How to pass JSON data to rest API in symfony2

I am creating rest api for symfony 2,but not able to pass JSON data to post method. $userform->isValid()always failed.
curl -v -H "Accept: application/json" -X POST -d '{"username":"hitesh","userpassword":"hitesh123"}' http://localhost/us/serenify/web/app_dev.php/user/login
This is the data I am passing for test purpose.
public function loginAction(Request $request)
{
return $this->processForm(new User(),$request);
}
private function processForm(User $user,$request)
{
$userform = $this->createForm(new UserType(), $user);
$content = $this->getRequest();
$userform->submit($content);
$key = md5(microtime().rand());
if ($userform->isValid())
{
if(trim($data['username'])=="" || trim($data['userpassword']==""))
{
$data=array(
"success"=>'false',
"msg"=>'username or password is blank'
);
$response = new Response(json_encode($data));
$response->setStatusCode(203);
$response->headers->set('Content-Type', 'application/json');
}
else
{
$username=trim($data['username']);
$userpassword=trim(md5($data['userpassword']));
$user = $this->getDoctrine()
->getRepository('SerenifyUserBundle:User')
->findOneBy(array('username' => $username, 'userpassword' => $userpassword));
if (!$user)
{
$data=array(
"success"=>'false',
"msg"=>'username or password is wrong'
);
$response = new Response(json_encode($data));
$response->setStatusCode(404);
$response->headers->set('Content-Type', 'application/json');
}
else
{
$data=array(
"success"=>'true',
"msg"=>'user has sucessfully logged in',
"username" => $username,
"sessionis" => $key,
);
$response = new Response(json_encode($data));
$response->setStatusCode(404);
$response->headers->set('Content-Type', 'application/json');
}
$response = new Response(json_encode($data));
}
}
else
{
$data=array(
"success"=>'false',
"msg"=>'invalid form content'
);
$response = new Response(json_encode($data));
$response->setStatusCode(404);
$response->headers->set('Content-Type', 'application/json');
}
return $response;
}
Above is my controller code.
When I print request value is does not show in JSON format.
Anyway to test or pass JSON data? I am creating login functionality.
FOSRestBundle was created for these purposes. And I think you should start to use it in your project. It has no overhead and is easy to use.
https://github.com/FriendsOfSymfony/FOSRestBundle
Regards.
I recently have had a need to something like this as I am extensively using AngularJS whose $http service sends data as JSON to my controllers.
I found a solution by implementing service which listens to incoming requests unpacks JSON and exposes it to Request object.
Check "The right way" section of this link.

Return http 500 with Slim framework

If somethings goes bad in my API i want to return a http 500 request.
$app = new Slim();
$app->halt(500);
It still return a http 200.
If i run this code:
$status = $app->response()->status();
echo $status; //Here it is 200
$status = $app->response()->status(500);
echo $status; //Here it is 500
it stills give me a http 200
The $app->response()->status(500); is correct, see the docs here.
Check to make sure you're calling $app->run(); after setting the status, this will prepare and output the response code, headers and body.
Edit, make sure you define a route or Slim will output the 404 response, this works:
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
$app->response()->status(500);
$app->get('/', function () {
// index route
});
$app->run();
If anyone still has this issue here is what I ended up doing:
Setup an error handler
$app->error(function (Exception $exc) use ($app) {
// custom exception codes used for HTTP status
if ($exc->getCode() !== 0) {
$app->response->setStatus($exc->getCode());
}
$app->response->headers->set('Content-Type', 'application/json');
echo json_encode(["error" => $exc->getMessage()]);
});
then, anytime you need to return a particular HTTP status throw an Exception with the status code included:
throw new Exception("My custom exception with status code of my choice", 401);
(Found it on the Slim forum)
If you have to push header after $app->run(), you can always rely on the header php function:
header('HTTP/1.1 401 Anonymous not allowed');
Slim framework v2 wiki status
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
$app->get('/', function () use ($app) {
$app->response()->setStatus(500);
$app->response()->setBody("responseText");
return $app->response();
});
$app->run();
or
$app->get('/', function () use ($app) {
$app->halt(500, "responseText");
});

Categories