I have an API gate in PHP with Slim 3 Framework (server1) and a web services server (server2) to access/edit the datas.
I handle user authentication and define my authenticated routes in server1. The dialog between server1 and server2 works with tokens.
I want to use my server1 to forward GET/POST requests to my server2. What is the best way to do that ?
With Slim on my server1, I can use the withRedirect method but I can't make it work with POST requests :
$app->post('/api/resource', function ($request, $response, $args) {
return $response->withRedirect("http://server2/api/resource?additionla_parameter=value");
});
Maybe should I use an app like Guzzle or a proxy ?
I personally would go the Guzzle route, meaning to just create a client on the server-side to communicate with server2, but there actually is a HTTP 307 response code for such purposes. It states that a client should not change the method (in your case the POST) during a redirect. Here is a nice little wrap-up: https://softwareengineering.stackexchange.com/questions/99894/why-doesnt-http-have-post-redirect/99966#99966
I just peeked at the slim source and the method accepts a second parameter for the status code which defaults to 302 when not set. See https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Response.php#L289. So just try this:
$response->withRedirect("http://postplease", 307);
That might work
Related
I'm using Slim PHP and want to redirect the user to /login if they are not logged in but try to access a page that requires a user to be logged in. When searching for how to build my middleware, I find variations of this code all over the place
class Auth{
public function requireLogin(Request $request, Response $response, $next){
if( !isLoggedIn() ) return $response->withRedirect('/login', 403);
return $next($request, $response);
}
}
for example in this SO answer and this Slim discourse answer.
The problem is that I can't get the combination of redirecting and HTTP 403 to work. From what I can tell, normal HTTP redirects are restricted to the HTTP codes 3xx. Indeed, the above code works fine when used with for example 302.
Am I missing something, or are all the answers that combine withRedirect and 403 "incorrect" (as in not causing an actual redirect of the users browser)?
If your application is an HTML website that's accessed using a web browser, then the browser will only redirect if the status code is a 3xx one.
If your application is an API that's accessed using an HTTP client then you have more leeway. For an API, you'd use a 403 or 401 status code to indicate that the request cannot be fulfilled without authorisation. You may also include a Location header to tell the client where to go to get authorisation, but of course it's up to the client if they follow up on that link.
Just started learning Slim3. Have been spending some time figuring out how to perform redirects with overriding original request type with no success.
I want the /origin route to perform the redirect to /dest route.
/origin route receives GET request performs validation and after success redirects with POST request to /dest uri route. Here is the screenshot. I think I am doing something dumb here:
$app->get('/origin', function($req,$res,$args)
{
$req= $req->withHeader('X-Http-Method-Override','POST');
return $res->withRedirect('/dest');
});
$app->post('/dest', function($req,$res,$args)
{
echo "this is destination page";
});
As noted in the comment, this is not possible as the request made by the browser is not in your control.
When you call ->withRedirect() you are sending a status code of 302 and a Location header to the HTTP client (web browser usually).
The web browser sees the 302 status code and then issues a new request to the URL in the Location header. The server has no control over this request and every web browser makes a GET request.
Now, if you want to redirect a POST request to another URL and keep the same POST method, then you can use the 307 status code with a Location header and the browser should do the right thing. Note that this code does not let you change a GET into a POST - it just keeps the same method as the original request for the followup redirection request.
I'm making a request to retrieve a JSON file to a server at a particular secure DocuSign uri. However, unless I put in the authorization information (which I do have), I am unable to have the file returned.
<?php
$json = file_get_contents("https://example.docusign.com/sensitiveIDs/moreID");
echo $json
?>
Where would I put in authorization information for the specific server/username/password/other info needed to access the particular DocuSign server using a method like this in PHP? Is there a better method to use for this scenario in PHP?
It depends on how the authorization is implemented. If its basic or digest HTTP authentication then specify it in the URL:
file_get_contents("https://$USER:$PASSWORD#example.docusign.com/sensitiveIDs/moreID");
Cookie based authentication is a lot more difficult (and probably easier to use Curl or even a more complex system like Guzzle. If its oauth2, then you probably want an oauth2 library.
Your call needs to include authentication to make the GET call to retrieve the file.
If your app is initiated by a human use Oauth to retrieve access and refresh tokens. Then included the access token with the GET request.
If your app is a "system app" that wants to autonomously retrieve the file, then you should authenticate by using X-DocuSign-Authentication -- include the following header in your HTTPS request. Since the request is HTTPS, the content is encrypted on the wire:
X-DocuSign-Authentication: <DocuSignCredentials><Username>{name}</Username><Password>{password}</Password><IntegratorKey>{integrator_key}</IntegratorKey></DocuSignCredentials>
Replace {name} with your email address (no braces), etc.
The bottom line is that you can't use the file_get_contents Php method. Instead, you'd do something like the following:
Use https://github.com/rmccue/Requests or a similar library to help with the https request. (http is not allowed due to security issues.)
(untested code)
$url = $base_url . $the_url_section_for_this_call
$headers = array('X-DocuSign-Authentication' =>
'<DocuSignCredentials><Username>your_name</Username><Password>your_password</Password><IntegratorKey>your_integrator_key</IntegratorKey></DocuSignCredentials>');
$request = Requests::get($url, $headers);
# Check that the call succeeded (either 200 or 201 depending on the method
$status_code = $request->status_code;
if ($status_code != 200 && $status_code != 201) {
throw new Exception('Problem while calling DocuSign');
}
$json = $request->body;
i try to implement the paypal IPN with slim.
see code here
they use curl to make a post request to an URL. Is it not possible to just change the URL in the slim response object?
other ways to send requests to somewhere with slim?
EDIT
I am talking about this line:
$res = curl_exec($ch);
what is the equivalent slim way to send a request to some url?
You can send PSR7 Requests with the help of HTTPlug.
You have to create some Adapter classes to tell HTTPlug how to create Slims Request and Response objects. In your code you just create your Slim Request and call the Client with this. You can choose between some clients, for example Curl or Socket.
If you want to send your user to PayPal in order for them to pay, then you need to create a form on your website which POSTs to PayPal directly.
The code you linked to is a POST request from PayPal back to your server. To handle that in Slim, you create a post route:
$app->post('/paypal-ipn', PayPalIpnAction::class);
Within your Action class you need to send POST request back to PayPal:
class PayPalIpnAction
{
public function __invoke($request, $response, $args)
{
$dataFromPaypal = $reqest->getParsedBody();
// Validate data from PayPal using HTTPlug, Guzzle or
// you use can the PayPal example code directly.
// If data is valid, process data and do whatever you
// need to with it.
// All done. Return the response.
return $response;
}
}
Note that the verification step back to PayPal isn't directly related to the handling of the notification in Slim as it's part of your code for handling the notification.
I'm creating an API for a site that allows the user to login via the API. I'm using Guzzle, but the question is how do I use the Cookies Plugin with Guzzle? In cURL I can use a cookie file, and pass this along with requests. But the example on the Guzzle docs looks confusing.
use Guzzle\Http\Client;
use Guzzle\Plugin\Cookie\CookiePlugin;
use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
$cookiePlugin = new CookiePlugin(new ArrayCookieJar());
// Add the cookie plugin to a client
$client = new Client('http://www.test.com/');
$client->addSubscriber($cookiePlugin);
// Send the request with no cookies and parse the returned cookies
$client->get('http://www.yahoo.com/')->send();
// Send the request again, noticing that cookies are being sent
$request = $client->get('http://www.yahoo.com/');
$request->send();
echo $request;
It seems to be making 3 requests. I don't understand why it's making a request to test.com, then twice to yahoo.com. Why are you not able to make 1 request?
It's just an example... You don't have to make three requests. Just attach the cookie plugin to your client and you're good.