Underscore in request header in Laravel - php

why laravel doesn't accept vars with underscore from request header?
I made a simple request example with a variable: "token_auth" with value 123 , but inside in my route doesn't get this value.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class Test extends Controller
{
public function teste(Request $request){
dd($request->header());
}
}
only prints header with no underscore:
array:9 [
"thisheadernounderline" => array:1 [
0 => "312321"
]
"cache-control" => array:1 [
0 => "no-cache"
]
"postman-token" => array:1 [
0 => "3c461fd1-5bea-4100-9926-81c14cb5810c"
]
"user-agent" => array:1 [
0 => "PostmanRuntime/7.1.1"
]
"accept" => array:1 [
0 => "*/*"
]
"host" => array:1 [
0 => "localhost"
]
"cookie" => array:1 [
0 => "XSRF-TOKEN=eyJpdiI6IkJwM3pjVkFBb2hxS2d4MDFcL2srM0h3PT0iLCJ2YWx1ZSI6IiszRzhoTzV0VzN5YUkydUNUTGR5aENVd291ZW01SkZ4V2ZxQkNDTGJwbDlyMFFJZGxzNnorMkF0VUNTbHpoRndLV3FmbndJWFhkXC9cL3IzOGZvN25zN3c9PSIsIm1hYyI6IjQwZWQ1YmJhM2VjM2I3N2RiNWZlYjcwYjZmYzQ0NDk5YjkwZDc4YzRjNGQwZjQxNDVkOGU1NDU0MTA0OWI2YWYifQ%3D%3D; laravel_session=eyJpdiI6IitSckpmOFI1TmpuXC9SSUt2QVY3VlFRPT0iLCJ2YWx1ZSI6IlwvVk1EaDdYdDNxRTZLNytRcnZDTlNiaVlFTWVRVmNUOHlyVnFia0pDeE9HNWpNa3QrWlBsNnNoVEduVkhrMUhkYURoNDI4cW9RdXVHU0lIS0JZN2REQT09IiwibWFjIjoiNWJmYmJmNTdmMzJkZjQ1OGQ4NTM1NjhhMzQxNDk5NWUxOTA5OGVjOThkODkyNDgwZTA2NzEyYjFlZmE2YjVjOSJ9"
]
"accept-encoding" => array:1 [
0 => "gzip, deflate"
]
"connection" => array:1 [
0 => "keep-alive"
]
]
is there any workaround to solve this?
And I cant change this because this variable comes from an API (aready asked to change but they wont wanna change).
Already tried with laravel 5.4 and laravel 5.6.
ps: with simple php works fine (no laravel framework)

This worked for my scenario.
I used this workaround in Laravel to solve my problem:
foreach (getallheaders() as $name => $value) {
echo "$name: $value\n";
}
output:
token_auth: 123
cache-control: no-cache
Postman-Token: f5bf7878-1f64-4ee8-907a-991d73ab8667
User-Agent: PostmanRuntime/7.1.1
Accept: */*
Host: localhost
cookie: XSRF-TOKEN=eyJpdiI6IkJwM3pjVkFBb2hxS2d4MDFcL2srM0h3PT0iLCJ2YWx1ZSI6IiszRzhoTzV0VzN5YUkydUNUTGR5aENVd291ZW01SkZ4V2ZxQkNDTGJwbDlyMFFJZGxzNnorMkF0VUNTbHpoRndLV3FmbndJWFhkXC9cL3IzOGZvN25zN3c9PSIsIm1hYyI6IjQwZWQ1YmJhM2VjM2I3N2RiNWZlYjcwYjZmYzQ0NDk5YjkwZDc4YzRjNGQwZjQxNDVkOGU1NDU0MTA0OWI2YWYifQ%3D%3D; laravel_session=eyJpdiI6IitSckpmOFI1TmpuXC9SSUt2QVY3VlFRPT0iLCJ2YWx1ZSI6IlwvVk1EaDdYdDNxRTZLNytRcnZDTlNiaVlFTWVRVmNUOHlyVnFia0pDeE9HNWpNa3QrWlBsNnNoVEduVkhrMUhkYURoNDI4cW9RdXVHU0lIS0JZN2REQT09IiwibWFjIjoiNWJmYmJmNTdmMzJkZjQ1OGQ4NTM1NjhhMzQxNDk5NWUxOTA5OGVjOThkODkyNDgwZTA2NzEyYjFlZmE2YjVjOSJ9
accept-encoding: gzip, deflate
Connection: keep-alive

Related

Symfony 6 | Consume streamed file and send it back to the client

I am developing an administrator website.
There is a section that, when a button is pressed, sends a request to my Symfony backend and the Symfony backend makes an HTTP request to another API that responds with a raw Excel file.
The flow Im trying to make is:
Admin panel [http request] -> Symfony Backend [http request] -> Another API [Generate file and streams it back]
Another API [Streamed Excel file] -> Symfony Backend [Consume the stream] -> Admin panel [Save in device]
I tried doing it like this:
ReportsService
public function reserves_report(String $date1, String $date2): FileForwardResponse {
// This calls to the API to get the streamed file
$guestTypesHttpResponse = $this->httpClient->request(
'GET',
$this->get_endpoint('reports') . "/" . $date1 . "/" . $date2
);
// This class is just to organize things
return new FileForwardResponse(
$guestTypesHttpResponse->getHeaders(),
$guestTypesHttpResponse->getContent(),
);
}
Controller
public function reserves_report(): Response
{
$this->sessionService->singUserIn();
$fileResponse = $this->reportsService->reserves_report($date1, $date2);
return new Response(
$fileResponse->content,
200,
$fileResponse->headers,
);
}
What I was expecting to do is to recive the entire streamed file from the API to the Symfony backend and then use the headers from the API to make it available to download from the client since the headers looks like this:
+headers: array:12 [▶
"connection" => array:1 [▶
0 => "Keep-Alive"
]
"keep-alive" => array:1 [▶
0 => "timeout=5, max=100"
]
"x-ratelimit-limit" => array:1 [▶
0 => "600"
]
"x-ratelimit-remaining" => array:1 [▶
0 => "596"
]
"content-type" => array:1 [▶
0 => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8"
]
"content-disposition" => array:1 [▶
0 => "attachment; filename="filename.xlsx""
]
"expires" => array:1 [▶
0 => "Mon, 26 Jul 1997 05:00:00 GMT"
]
"last-modified" => array:1 [▶
0 => "Sat, 11 Feb 2023 15:51:36"
]
"cache-control" => array:1 [▶
0 => "cache, must-revalidate"
]
"pragma" => array:1 [▶
0 => "public"
]
"transfer-encoding" => array:1 [▶
0 => "chunked"
]
"date" => array:1 [▶
0 => "Sat, 11 Feb 2023 21:51:36 GMT"
]
]
And the response content looks like this:
What I got when I hit my Symfony endpoint is a 0 bytes file named filename.
If I hit the APIs endpoint from the browser directly it downloads it just right but I would like to know if there is any way to do it through Symfony http request.

How to read a json_decode result and dump it?

i have a little problem with my json response.
I dumped it in my php code, and the result is what i attached here
How can I dump the statusText ?
I've already tried to decode it, and i've tried this too:
dump($myVar['statusText']);
or something like that
(to obtain the dump of my json i've posted, i've just did
dump($myVar); )
JsonResponse {#325
#data: "{"code":"OK","status":"ok","data":{"UUID":"f239ae18-98af-4224-8b4f-7713c71a5576","order":{something here },"orderRows":[something else here}}"
#callback: null
#encodingOptions: 271
+headers: ResponseHeaderBag {#326
#computedCacheControl: array:2 [
"no-cache" => true
"private" => true
]
#cookies: []
#headerNames: array:4 [
"content-type" => "Content-Type"
"access-control-allow-origin" => "Access-Control-Allow-Origin"
"cache-control" => "Cache-Control"
"date" => "Date"
]
#headers: array:4 [
"content-type" => array:1 [
0 => "application/json; charset=utf-8"
]
"access-control-allow-origin" => array:1 [
0 => "*"
]
"cache-control" => array:1 [
0 => "no-cache, private"
]
"date" => array:1 [
0 => "Mon, 06 May 2019 08:15:28 GMT"
]
]
#cacheControl: []
}
#content: "{"code":"OK","status":"ok","data":{"UUID":"f239ae18-98af-4224-8b4f-7713c71a5576","order":{something},"orderRows":[something else}}"
#version: "1.0"
#statusCode: 200
#statusText: "OK"
#charset: null
}
Just wanna see
"status" => 'ok' and my life would be perfect :D
Looking at this output, it looks like the code is stored in the content also.
"status":"ok"
For this reason, following this documentation on the getData() method, you should be able to retrieve the status:
$data = $myVar->getData();
var_dump($data->status);
It is expected that this would return a string of "ok".

Curl Response handling with Guzzle 6.2 with Laravel 5.3

I am trying to obtain a JSON response from an end point using Guzzle 6.2 with Laravel 5.3.
I am using the following code to make a get request:
$client = new GuzzleHttp\Client([
'base_uri' => 'https://192.xx.xxx.xx6/',
'timeout' => 2.0
]);
$response = $client->request('GET',
'/fineract-provider/api/v1/clients/388?tenantIdentifier=default&pretty=true', [
'verify' => false,
'auth' => ['<username>', '<password>']
]
);
var_dump($response);
Which outputs the following response:
Response {#282
-reasonPhrase: "OK"
-statusCode: 200
-headers: array:7 [
"Server" => array:1 [
0 => "Apache-Coyote/1.1"
]
"Access-Control-Allow-Origin" => array:1 [
0 => "*"
]
"Access-Control-Allow-Methods" => array:1 [
0 => "GET, POST, PUT, DELETE, OPTIONS"
]
"Content-Type" => array:1 [
0 => "application/json"
]
"Transfer-Encoding" => array:1 [
0 => "chunked"
]
"Vary" => array:1 [
0 => "Accept-Encoding"
]
"Date" => array:1 [
0 => "Sat, 04 Feb 2017 15:51:10 GMT"
]
]
-headerNames: array:7 [
"server" => "Server"
"access-control-allow-origin" => "Access-Control-Allow-Origin"
"access-control-allow-methods" => "Access-Control-Allow-Methods"
"content-type" => "Content-Type"
"transfer-encoding" => "Transfer-Encoding"
"vary" => "Vary"
"date" => "Date"
]
-protocol: "1.1"
-stream: Stream {#280
-stream: stream resource #297
wrapper_type: "PHP"
stream_type: "TEMP"
mode: "w+b"
unread_bytes: 0
seekable: true
uri: "php://temp"
options: []
}
-size: null
-seekable: true
-readable: true
-writable: true
-uri: "php://temp"
-customMetadata: []
}
}
But this is not the response I expect. However, when I make the same request in my browser it gives the correct output as below:
What am I doing wrong here?
The Response object contains more information than just the response. You can get the actual output like this:
$output = (string)$response->getBody();
It might be necessary (in certain cases) to cast the result to a string, because the actual result is a stream.
Guzzle documentation: Responses

Guzzle and Form + Basic Auth issues with Laravel

I have been looking into grabbing some data from Livecoding.tv, and i am currently reusing my Oauth2 controller that i used for the twitch API, which should be pretty straightforward.
If someone does not know, the flow used by Oauth is the following:
Redirect user to third party Oauth link with your app code.
User Authorizes.
User redirected to your website again, with an Authorized token, that you can then post to the third party to get your refresh token etc.
Now on step 3, i am running into some problems. Here is the description and example by the developer:
Getting token: https://www.livecoding.tv/o/token/
Header
A HTTP Basic auth, using the application_code as username, and application_secret as password, as seen in the example below.
POST Body
code=EXAMPLE Token gotten from redirect
grant_type=Your grant type (authorization_type)
redirect_uri=Your redirect URL
And here is an example cURL request from the documentation of a working curl request.
curl -X POST -d "grant_type=authorization_code&code=Php4iJpXGpDT8lCqgBcbfQ2yzhB0Av&client_id=vCk6rNsC&redirect_uri=http://localhost/externalapp" -u"vCk6rNsC:sfMxcHUuNnZ" https://www.livecoding.tv/o/token/
So i tried to make this in Postman(https://www.getpostman.com/), which worked out of the box, i then asked Postman to convert this to PHP, to see if i had missed something. Here is the outcome of the working Postman request:
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://www.livecoding.tv/o/token/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "code=SOMECODE&client_id=SOMECLIENTID&redirect_uri=SOMEURL&grant_type=authorization_code",
CURLOPT_HTTPHEADER => array(
"authorization: Basic U09NRVVTRVI6U09NRVBBU1NXT1JE",
"cache-control: no-cache",
"content-type: application/x-www-form-urlencoded",
"postman-token: c8df4bbc-cbd0-73eb-df35-80210989db33"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
I was pretty happy this worked out right away, so i just needed to make a Guzzle client do the same, which already works for the Twitch Oauth, here is my code for that:
{
$providers = ServiceProvider::findOrFail(2);
$client = new Client([
'base_uri' => $providers->oauth_url . '/token/',
'form_params' => [
'code' => $token,
'grant_type' => 'authorization_code',
'client_id' => $providers->application_code,
'redirect_uri' => $providers->redirection_url
],
'auth' => [
'somestring',
'someotherstring',
],
'headers' => [
'Content type' => 'application/x-www-form-urlencoded',
'cache-control' => 'no-cache'
]
]);
$response = $client->request('POST');
return ($response);
}
This would just return me with a 401, so i decided to do some debugging, and here is the request that comes, if i stop it right before it is sent:
Client {#637 ▼
-config: array:10 [▼
"base_uri" => Uri {#676 ▼
-scheme: "https"
-userInfo: ""
-host: "www.livecoding.tv"
-port: null
-path: "/o/token/"
-query: ""
-fragment: ""
}
"form_params" => array:4 [▼
"code" => "SOMECODE"
"grant_type" => "authorization_code"
"client_id" => "SOMECLIENTID"
"redirect_uri" => "http://REDIRECTURI"
]
"auth" => array:2 [▼
0 => "SOMECLIENTID"
1 => "SOMECLIENTSECRET"
]
"headers" => array:3 [▼
"Content type" => "application/x-www-form-urlencoded"
"cache-control" => "no-cache"
"User-Agent" => "GuzzleHttp/6.2.1 curl/7.26.0 PHP/5.6.27-1~dotdeb+7.1"
]
"handler" => HandlerStack {#664 ▼
-handler: Closure {#671 ▼
class: "GuzzleHttp\Handler\Proxy"
parameters: {▼
$request: {▼
typeHint: "Psr\Http\Message\RequestInterface"
}
$options: {▼
typeHint: "array"
}
}
use: {▼
$default: Closure {#669 ▼
class: "GuzzleHttp\Handler\Proxy"
parameters: {▼
$request: {▼
typeHint: "Psr\Http\Message\RequestInterface"
}
$options: {▼
typeHint: "array"
}
}
use: {▼
$default: CurlMultiHandler {#634 ▼
-factory: CurlFactory {#667 ▼
-handles: []
-maxHandles: 50
}
-selectTimeout: 1
-active: null
-handles: []
-delays: []
}
$sync: CurlHandler {#666 ▼
-factory: CurlFactory {#665 ▼
-handles: []
-maxHandles: 3
}
}
}
file: "/LARAVELPATH/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php"
line: "25 to 29"
}
$streaming: StreamHandler {#670 ▼
-lastHeaders: []
}
}
file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php"
line: "49 to 53"
}
-stack: array:4 [▼
0 => array:2 [▼
0 => Closure {#672 ▼
class: "GuzzleHttp\Middleware"
parameters: {▶}
file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Middleware.php"
line: "54 to 69"
}
1 => "http_errors"
]
1 => array:2 [▼
0 => Closure {#673 ▼
class: "GuzzleHttp\Middleware"
parameters: {▶}
file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Middleware.php"
line: "148 to 150"
}
1 => "allow_redirects"
]
2 => array:2 [▼
0 => Closure {#674 ▼
class: "GuzzleHttp\Middleware"
parameters: {▶}
file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Middleware.php"
line: "27 to 43"
}
1 => "cookies"
]
3 => array:2 [▼
0 => Closure {#675 ▼
class: "GuzzleHttp\Middleware"
parameters: {▶}
file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Middleware.php"
line: "216 to 218"
}
1 => "prepare_body"
]
]
-cached: null
}
"allow_redirects" => array:5 [▼
"max" => 5
"protocols" => array:2 [▼
0 => "http"
1 => "https"
]
"strict" => false
"referer" => false
"track_redirects" => false
]
"http_errors" => true
"decode_content" => true
"verify" => true
"cookies" => false
]
}
As you can see here, there is just a parameter called 'auth' in here, and not the basic auth that is documented in Guzzle here: http://docs.guzzlephp.org/en/latest/request-options.html#auth
Though i would mention that the correct values are entered.
For the debugging i just did dd($client), i do not know if this will give me all the answers?
So the other possibility is to base64 encode it (like it is done in basic auth in general), and add a "Authorization" header manually, i tried that, but i am unaware if i am doing it correctly when i do:
$credentials = base64_encode($clientvariable . ':' . $clientsecretvariable)
Would that be the correct way? Though i would rather use this as a last resort if i do not get the auth parameter to work in Guzzle.
I am aware of the other Stackoverflow questions about Guzzle and basic auth, and yes i have read them, hopefully i have provided with enough information to show that.
The problem here was related to how i return the response from Guzzle.
Since i just returned $response, which is just the stream, the browser never got anything returned, and since chrome auto refresh, he runs the request twice, and on the second time, i would have just my code twice, which would have returned an error.
I ended up going crazy about this, until i changed browser, and saw that nothing ever happened, which pointed me in the right direction.

Use Laravel passport authentication in API

I am using Laravel Passport Authentication in my project. I want to use passport authentication only in API so I am trying to generate client_id and client_secret using below code but it returns NULL
I have written this code in my routes/api.php
Route::post('/gen_client', function () {
$http = new GuzzleHttp\Client([
'headers' => [ 'Content-Type' => 'application/json' ]
]);
$response = $http->post(url('/') . '/oauth/clients',
['body' => json_encode(
[
'id' => 'ovais.khan#gmail.com',
'name' => 'Ovais2',
'redirect' => url('/') . '/callback'
]
)
]
);
$response_body = json_decode((string)$response->getBody(), true);
var_dump($response_body);
});
Suppose if I have generated client_id using command line php artisan passport:client
now I want to authorized access token but it returns NULL
Route::post('callback', function (Request $request) {
$http = new GuzzleHttp\Client();
$oauth_client = DB::table('oauth_clients')->where('id', '=', 'ovais.khan#gmail.com')->first();
$response = $http->post(url('/') . '/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => $oauth_client->id,
'client_secret' => $oauth_client->secret,
'redirect_uri' => url('/') . '/callback',
'code' => $request->code,
],
]);
$response_body = json_decode((string)$response->getBody(), true);
var_dump($response_body);
$access_token = $response_body['access_token'] ;
$refresh_token = $response_body['refresh_token'];
});
dd(url('/') . '/oauth/clients'); send me the output:
http://localhost/project/public/oauth/clients
dd($response); send me the output:
Response {#224
-reasonPhrase: "OK"
-statusCode: 200
-headers: array:7 [
"Date" => array:1 [
0 => "Sat, 29 Oct 2016 10:19:24 GMT"
]
"Server" => array:1 [
0 => "Apache/2.4.23 (Win32) OpenSSL/1.0.2h PHP/7.0.9"
]
"X-Powered-By" => array:1 [
0 => "PHP/7.0.9"
]
"Cache-Control" => array:1 [
0 => "no-cache"
]
"Set-Cookie" => array:1 [
0 => "laravel_session=eyJpdiI6Ikx5WXJpTEFvZ0ZiNFwvbFwvYWZRQWxEZz09IiwidmFsdWUiOiJVM29lbTNYSnZwdld5ZHdVRk1IK1hJbG9RenNQa1owS1lRMEFYQ3lVamluV3JcL2RwaVQyRkpsZzkwQ082OU94QkJiSUpGQTZpeTMxWjdpMEtCZ1Byc3c9PSIsIm1hYyI6IjQwNTcwZTQ4YzQ2OGIwODQ5Y2NjMzBiMmIyNmI5MTVkNTY0ZjI0OGQ1Y2M1NTVjYTljNmU4Mjk2Nzg0Yjk2MmMifQ%3D%3D; expires=Sat, 29-Oct-2016 12:19:24 GMT; Max-Age=7200; path=/; HttpOnly"
]
"Content-Length" => array:1 [
0 => "4709"
]
"Content-Type" => array:1 [
0 => "text/html; charset=UTF-8"
]
]
-headerNames: array:7 [
"date" => "Date"
"server" => "Server"
"x-powered-by" => "X-Powered-By"
"cache-control" => "Cache-Control"
"set-cookie" => "Set-Cookie"
"content-length" => "Content-Length"
"content-type" => "Content-Type"
]
-protocol: "1.1"
-stream: Stream {#222
-stream: stream resource #234
wrapper_type: "PHP"
stream_type: "TEMP"
mode: "w+b"
unread_bytes: 0
seekable: true
uri: "php://temp"
options: []
}
-size: null
-seekable: true
-readable: true
-writable: true
-uri: "php://temp"
-customMetadata: []
}
}
Can anyone help me out?
Waiting for positive response.
My teamlead has been resolved this problem. Please check the below link:
Laravel's 5.3 passport and api routes
The reason you are getting NULL for $response_body is when you are setting the variable you are type hinting $response->getBody() as a string, what you are actually getting is an instance of Stream. Also you're trying to json_decode a class, not a json string. $response_body = json_decode((string)$response->getBody(), true); If you would like a JSON response you can do $response_body = $response->json();
For more information these sections of the GuzzleHttp docs will be really useful:
http://guzzle3.readthedocs.io/http-client/response.html#response-body and http://guzzle3.readthedocs.io/http-client/entity-bodies.html

Categories