Swagger.io Slim Framework POST errors - php

I used Swagger to generate a Slim framework for a server. Without editing anything, I am testing the basic functions. I have one located at /user/login. Here is the script I have for it:
$app = new Slim\App();
$app->POST('/user/login', function($request, $response, $args) {
$queryParams = $request->getQueryParams();
$username = $queryParams['username'];
$password = $queryParams['password'];
$response->write("Will not work");
return $response;
});
$app->GET('/user/{user_id}', function($request, $response, $args) {
$response->write('Works');
return $response;
});
However, when I try to POST to the url using Postman (chrome app), it results in a 500 error. If I try any of the GET methods, it works. It only seems to be happening with the POST methods.
I have it running on an Ubuntu machine, with Apache2 installed with PHP. I have updated everything to the latest available versions. ModRewrite is enabled, and the override is set to all. Please help! I am at such as loss at this point.

I found the error.
Notice that I have two urls, one at /user/login and /user/{user_id}, because of the two starting /user urls, it confuses and doesn't know which to use, resulting in a 500 error.
Switching the /user/login to /login corrected the issue.
I feel stupid for not knowing that would happen.

Related

I'm transitioning my API from slim-3 to slim-4 and I'm struggling to figure out how to add JWT to the middleware

I'm using composer to install the slim-skeleton. Those built in routes work as expected. I understand how to add in my previous routes and database connections, but I've been struggling on how to add in any JWT library. I've searched and searched but I'm not finding much documentation for Slim-4 and what I've tried always seems to fail one way or another.
So for example I use composer to install tuupola/slim-jwt-auth and it says to add the following code:
$app = new Slim\App;
$app->add(new Tuupola\Middleware\JwtAuthentication([
"secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
but where or how exactly do I add it to the middleware? Does it need to be added to app/middleware.php? All the documentation I read has a completely different file structure with other directories and whatnot. Once this is placed in the correct spot it looks like when a request is made without a token I should get a 401 Unauthorized response.
After that part is working I know I need to create a route to get my access token, but I'm not seeing anything about that in this library so I would assume I need another library to encode my token and return it from my request.
Once I actually get a token response and pass it in the headers for my actual request route I would assume I do something like the following
$app->get("/protected-route-name", function ($request, $response, $arguments) {
$token = $request->getAttribute("token");
// Not sure what to put next to verify the token and allow the response or display a error if there is no token or the token in invalid.
});
I'm open to firebase or any JWT library if someone has one they like and that works well, I just need some direction as I feel all the documentation is lacking.
use \Firebase\JWT\JWT;
get token
$headers = apache_request_headers();
if(isset($headers['Authorization'])){
$decoded = JWT::decode($headers['Authorization'], $publicKey, array("RS256"));
.... verify token.
}
$jwt = JWT::encode($payload, $privateKey, "RS256");
boom done.
you don't even really need to use middle ware to do this.
slim made itself way overly complex with that.
But the truth is between slim3 and slim 4, on a very basic setup, the only thing that has changed is the getBody() on the json writing.
honestly, not really sure how useful this is anymore to be honest. everything is cloudbased now. Only reason I found this is trying to figure out how to use Google Identity Platform with Slim.

Why are my cookies not persisting in Laravel (using Homestead, Vagrant)?

I've been using Laravel from command prompt in Windows 10, but the difficulty of switching between projects has made me switch to using Homestead. However, in a new project I have started there, I can't for the life of me get cookies to persist.
Here is my current code (for debugging this problem only):
use Illuminate\Support\Facades\Cookie;
// ......
public function __construct(Request $request) {
$customer_id = Cookie::get('customer_id');
if(!$customer_id) {
Cookie::queue('customer_id', time(), 3600);
}
dd($customer_id);
}
Expected output: On consecutive page loads, the visitor will see the same unix timestamp they initially opened the page at (I understand this is not a good way of handling it, again, this is just for reproducing the error.)
Reality: Every pageload will produce a different timestamp.
I've looked up as many discussions as I could find. Solutions that I tried:
Using the Route method of declaring cookies
Using good-old PHP setcookie
Using Cookie:make, and Cookie:forever
Adding 'customer_id' in the exceptions among EncryptCookies
Placing the route in the web middleware
Erasing php artisan cache, restarting vagrant
Making the session folder editable through chmod
Yet still, after applying all the above, the cookie is still gone after every page load.
Since I had no prior problem like this through Xampp's PHP, I have to assume there is a (hopefully) trivial and obvious problem with Vagrant that I don't yet know. Any advice is appreciated!
Queued cookies are only sent with responses, so be sure that your controller function does return one.
use Illuminate\Support\Facades\Cookie;
// ......
public function __construct(Request $request) {
$customer_id = Cookie::get('customer_id');
if(!$customer_id) {
Cookie::queue('customer_id', time(), 3600);
}
}
public function foo() {
...
return response('some text');
}
Also, if using some kind of api you have to add a middleware to include the cookies on the response. See Laravel 5.4 - Cookie Queue

How can multiple method calls be chained on slim's response object?

I want to chain multiple method calls on slims's $response object, but if i do i get an error ( status 500) and nothing happens.
This might aswell be a lack of basic PHP knowledge, i am not very experienced in PHP and it is my first time working with slim, or any serverside / API framework for that matter.
I have tried flipping arround the order of the calls, and doing them in different lines but to no awail. The long term goel of this, to build an API for an update application. So i will have to handle get requests with multiple parameters, evaluate them and depending on the results, do and return deffirent responses.
// this one fails, i set the status to 900 on purpose just to see what happens
$app->get('/', function (Request $request, Response $response, array $args) {
$response->getBody()->write("Slim main page")->withStatus(900);
return $response;
});
The first example does give me an 500 error on the network tab. This would suggest some type of syntax error i guess? If i alter this route a little bit to look like this :
# this one works fine, except the status code setting gets ignored, but why?
$app->get('/', function (Request $request, Response $response, array $args) {
$response->write("Slim main page")->withStatus(900);
return $response;
});
things alsmost work out, but the status code is not set for some reason.
I would expect the first one, to return the string "slim main page" with the status code 900. Even if i use a non made up status code, this setting gets ignored.
The second code block ist just an alteration for testing purposes.
I am pretty sure this a newby thing but i am really lost here, so any advice, or some fool proof articles / docs besides the slim docs are appreciated.
The write method returns the number of bytes written to the stream (and not the new response object). Try this:
$app->get('/', function (Request $request, Response $response, array $args = []) {
$response->getBody()->write('Slim main page');
$response = $response->withStatus(200);
return $response;
});
Notice 1: Enable the error details on dev: 'displayErrorDetails' => true
Notice 2: The HTTP code 900 is an invalid status code for Slim and will throw the following execption.
Type: InvalidArgumentException
Message: Invalid HTTP status code
File: vendor/slim/slim/Slim/Http/Response.php
Line: 228

How to queue cookies in lumen?

I am trying to queue various cookies in response in Lumen.
I've added \Illuminate\Cookie\ into my Composer.
I added Following code in app.php
$app->singleton('cookie', function () use ($app) {
return $app->loadComponent('session', 'Illuminate\Cookie\CookieServiceProvider', 'cookie');
});
$app->bind('Illuminate\Contracts\Cookie\QueueingFactory', 'cookie');
In My Controller, I am trying the following code
Cookie::queue(Cookie::make('test', 'tada', 10, '/'));
//Few more business logic here: before returning the response
$response = new \Illuminate\Http\Response('exit');
return $response->withHeaders($headers);
I can see my queued cookies using Cookie::getQueuedCookies()
but still, after a response, my cookie is nowhere to be found.
I tried various answers from StackOverflow questions but still couldn't resolve it
I can't use response()->withCookie() solution because I am creating cookies at various points of my code, and can't pull them together at the time of response
Queued cookies in Laravel are handled by the \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse class.
It begs the question why you'd use Lumen if you wanted cookies support but you should be able to add this middleware to your HTTP stack in Lumen.

Functional test in Laravel with External URL ( Google Login)

I'm trying to test the Google Login in my Laravel App.
When I try to reach Google Login page I get a 404.
My idea is that in TestCase.php, I have a variable:
protected $baseUrl = 'http://laravel.dev';
So, it could make a conflict.... well the thing is I don't know how to do it, or to fix it!
Here is my code:
$this->visit('/auth/login')
->click('google');
dump(Request::url()); // https://accounts.google.com/o/oauth2/auth
$this->dump(); --> Gives me a 404 page
Any idea is welcome !
The answer is NO. The framework doesn't support it. If you dig a little bit you will found when you test with "visit", the request was not actually send out. In the call method of class MakesHttpRequests, it initialize a laravel http kernel and put the request thru it. No http request was actually issued.
$kernel = $this->app->make('Illuminate\Contracts\Http\Kernel');
$this->currentUri = $this->prepareUrlForRequest($uri);
$this->resetPageContext();
$request = Request::create(
$this->currentUri, $method, $parameters,
$cookies, $files, array_replace($this->serverVariables, $server), $content
);
$response = $kernel->handle($request);
The only way you can try is to mock this part.

Categories