I am building an application which will eventually reside on the same domain where another application resides; both of which are written in PHP. One is a Laravel application and the other a Magento 1.9 store.
To authenticate the user, the Laravel application requires that a certain cookie be set by the Magento store's response, subsequently retrieved and parsed, all before authentication may continue.
My current strategy is a POST to a custom controller which delivers multiple Set-Cookie headers from the Magento store.
The one I need is something like:
Set-Cookie: auth_token=TheValueWeNeedToContinueAuthenticating; domain='.mydomain'; ...
The server I am testing on is an in-house staging environment. The server's VHost is set to Laravel's public directory, as usual.
The Magento store is on a different server however the TLD is the same .mydomain
I have verified the response in Postman, I am indeed returning the cookie with the correct Set-Cookie in place, however it is not visible in my Laravel application as the other cookies from Magento, are. The other cookies were verified within the response as I dumped Guzzle's CookieJar and still received all but the cookie I am looking for.
I am using PHP's Guzzle HTTP Library to post from a Laravel 5.6 app using PHP 7.1
The Magento1.9 store unfortunately uses PHP/5.6.35
When I dump the HTTP response I am getting the cookies which would normally receive had I actually visited any page within the store.
What else could I check to ensure I am taking to right approach to receiving this cookie? Https is the transmission protocol, and the content-type is x-www-form-urlencoded if that will assist an answer in any way.
Thank you.
UPDATE 1.0 - I was able to get a clean error reading from the request being sent.
{"status":"error","message":"invalid request"}
Here is my Guzzle Post request
$jar = new \GuzzleHttp\Cookie\CookieJar;
// Logging my error output -- I can share this if I must
$debug_file = fopen('../storage/logs/debug.txt', 'a');
try {
$payload = 'Knock, knock';
$url = '/api/for/post';
$client = new Client([
'base_uri'=> 'https://mySubdomain.myDomain.com',
'debug' => $debug_file,
'cookies' => $jar,
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
]
]);
$request = new \GuzzleHttp\Psr7\Request('POST', $url, [], $payload);
$rsp = $client->send($request);
dd($rsp->getBody()->read(1024));
$response->getBody()->read(1024) returns the error message
Related
I have project divided into frontend and backend. Backend is available on mydomain.com/api and I need to develop frontend project which cooperate with backend on mydomaion.com/api.
First problem was CORS - It`s ok. I allowed CORS.
But now I am facing to second problem. When I sign-in in frontend, backend set BEARER token.
setcookie('BEARER', $token, 0, '/', '', false, true);
I expect when I send next request to API, cookie BEARER header automatically attached. Unfortunatelly no headers attached and therefore I get response 401 Unauthorized because I am not logged in.
I think that problem is domain. Frontend running on my local PC mydomain.test and API running on mydomain.com.
I think I need something like this:
setcookie('BEARER', $token, 0, '/', '*', false, true);
But this is not working too.
Solve somebody same problem?
I dont know what are you using in your backend, but i think your problem is on your CORS config. Normally you need to allow the origin you are using, headers and credentials. In ASP.NET CORE it would look something like this:
builder.WithOrigins("http://localhost:8080")
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed(origin => true)
.AllowCredentials();
And since you are using jwt token you need to add it:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
//your jwt options config
})
)
I have an application on Yii2.
I have an external vendor i want to redirect. For example, i am encrypting the current user info, and want to send that to the external vendor, so the user information is automatically populated on his website.
Everything works fine if i do that on the front end side using JS.
The problem i have is only my app server is whitelisted to the vendor. So i need to make the redirection happen on the backend.
I tried several method, and even with Guzzle HTTP, and it doesn't redirect.
TO be clear, i am not looking for a simple redirect, it is a form post on external URL.
I went though this post, but the problem remain the same...
Yii2 how to send form request to external url
Does anybody faced this issue?
If I understand you correctly, you want to POST data received from your frontend to the server of a third party company (let's call them ACME). Your webserver is whitelisted by ACME but your clients are not (which is good). You want to show a page on your server and not a page on the ACME server after the POST, right?
You have to send the data with a separate request from your server to the ACME server. You cannot create a HTML <form> and put the ACME server in the action parameter of it, because the request would be sent from the client and not your backend, failing at the whitelist. After you validate your client input, you can send it with guzzle to ACME.
With the status code you can decide if your request was successful or not. You can read more about guzzle here
The code sample below shows how you could POST the $payload (a fictional blog post if you will) as JSON to the ACME server and output a line with the request result.
$payload = [
'username' => 'john.doe',
'postContent' => 'Hello world',
];
$client = new GuzzleHttp\Client();
$response = $client->post('https://acme.example.org/endpoint',['http_errors' => false, 'json' => $payload]);
if($response->getStatusCode() === 200){
echo "Request OK";
}else{
echo "Request failed with status ".$response->getStatusCode();
}
I have a service app and I'm willing to download a file from an user's Drive using msgraph-sdk
I am able to upload a file using
$graph->createRequest("PUT", "/users/".$userId."/drive/items/root:/".$folderName."/".$fileName.":/content")
->upload($filePath);
But I am not able to download it. Here is the code I am using:
$graph = new Graph();
$graph->setAccessToken($accessToken);
$graph->createRequest("GET", "/users/".$userId."/drive/items/".$docId."/content")
->download($filePath);
The error is: PHP Warning: fclose(): 16 is not a valid stream resource in microsoft-graph/src/Http/GraphRequest.php on line 344
I could note that making a request to the URL https://graph.microsoft.com/v1.0/users/{USER_ID}/drive/items/{DOC_ID}/content using Postman and passing Authorization Bearer {ACCESS_TOKEN}, the response is the file's content, which is the expected behavior, but for some reason, calling it via PHP is not working.
Am I doing something wrong?
---- UPDATE ----
The problem seems to be related to the response I am getting after making the request. Documentation says that the response code will be 302 and I need to redirect to the address in Location header, but it looks like that the MS Graph (or Guzzle Client) is not being capable to redirect to the address. I tried editing GraphRequest.php to enable it when creating a Client like this:
$clientSettings = [
'base_uri' => $this->baseUrl,
'verify' => false,
'allow_redirects' => true,
'headers' => $this->headers
];
$client = new Client($clientSettings);
but it didn't work.
I believe this is a bug. I have logged it here. There is a fix checked in and we are getting ready to publish a new version of the SDK, so you should be able to pull in the fix soon. In the meantime, you can incorporate the PR and verify that it solves the problem that you are seeing.
I wrote a scheduling app in laravel 5 that basically builds some json from local storage and sends this to the controller and then the view. the view is mostly javascript that parses the json and builds the schedule. I would like to extend this to allow a client coder to generate their own json and post that to my app and have my app send them a full view / schedule back.
I'm using php 7 and the php -S options to bring up 2 servers - one hosting the main schedule that i have and one hosting the client test code that posts to the schedule.
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$uri ='/api/clientJSON';
$uri_token ='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEsImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDAwXC9hcGlcL2F1dGhlbnRpY2F0ZSIsImlhdCI6MTQ1Njg0NDI1NiwiZXhwIjoxNDU2ODQ3ODU2LCJuYmYiOjE0NTY4NDQyNTYsImp0aSI6IjI2ODZjZWIwNjI2ZDVmZWE1YmVlZjMwNzM0ZDhkMzZmIn0.hWrIGNGLlIHOLP9FltefsN066WOHpGTm2SmsF6feAsI';
$calendarJson = '{"auth":"test"}';
$client = new Client([
'base_uri' => 'http://localhost:8000',
'timeout' => 2.0,
]);
$response = $client->request('POST', $uri, [
'query'=>['token' => $uri_token],
'form_params' => [
'calendarJson' => $calendarJson
]
]);
echo $response->getBody();
this issue seems to be that while the body does echo out, its only pulling in the html page and all the dependent js / css files are not loaded. I'm clearly missing something fundamental about building my web service. Can someone enlighten me please?
While Guzzle is a PHP HTTP Client, it is not a web browser. As such it will perform HTTP requests, but it will not parse the response to determine if or what other files need to be downloaded to view the content properly.
As observed, if a request is actioned, and the response contains references for externally stored javascript, or CSS files, they will not be requested.
For years the internet has been very good at blurring the lines between content and presentation. As a service provider, you are interested in the content obtained from external sources, not how those external sources present it.
I've written a Wordpress Plug-in that interacts with Salesforce via the REST API. It successfully gets an Instance URL and an Authentication Token using a username/password.
I'm able to submit queries and create objects using wp_remote_post with GET and POST respectively.
However, when creating objects, though successfully created in the Salesforce instance, I get the following in response to my POST:
{"message":"HTTP Method 'POST' not allowed. Allowed are HEAD,GET,PATCH,DELETE","errorCode":"METHOD_NOT_ALLOWED"}
Using the same json body content from these requests, I am able to submit and create via the Salesforce Workbench with no problems at all. I get a proper response that looks like this:
{
"id" : "003E000000OubjkIAB",
"success" : true,
"errors" : [ ]
}
Is there something in the Headers that I'm sending that Salesforce only partially disagrees with? Here are some other arguments that are getting sent as a result of using wp_remote_post - http://codex.wordpress.org/HTTP_API#Other_Arguments
Here's the php code that's calling it:
$connInfo['access_token'] = get_transient('npsf_access_token');
$connInfo['instance_url'] = get_transient('npsf_instance_url');
$url = $connInfo['instance_url'] . $service;
$sfResponse = wp_remote_post($url, array(
'method' => $method,
'timeout' => 5,
'redirection' => 5,
'httpversion' => 1.0,
'blocking' => true,
'headers' => array("Authorization" => "OAuth ". $connInfo['access_token'], "Content-type" => "application/json"),
'body' => $content,
'cookies' => array()
)
);
The $content is being encoded via json_encode before it gets to this point.
Update:
It is specific to one of the extra CURL options being sent by the WP_Http_Curl class. I haven't yet narrowed down which one Salesforce is having a problem with.
The solution is disable redirection in the request. You have it as 5 (the default) -- it needs to be set to 0 for this to work.
The initial request works but Salesforce sends a location header as a part of the response (the URL of the newly created object). WordPress thinks it is being told that the URL moved and that it should try again at this new URL. The response you're seeing is the result of that second request to the actual object you just created. That URL doesn't accept POST requests apparently.
It's a bit odd for Salesforce to be sending such a header, but there's also some discussion going on on the WordPress side that WordPress shouldn't follow location headers for non-301/302 responses which would solve this.
Thanks for posting this by the way. You update made me start debugging WP_Http_Curl which made me realize it was actually making a second HTTP request.