How to access the page protected by basic auth using Faraday? - php

I have a php page I want to access and that page is protected by basic auth. I know the url and username/password, they are listed below in code:
url = 'https://henry.php' # note that it is a php website
username = 'foo'
password = 'bar'
Faraday provide basic auth function, their doc says that I should use the following code:
connection = Faraday.new(url: url) do |conn|
conn.basic_auth(username, password)
end
I want to get the response body of the above url to make sure that the basic auth indeed succeed and I can access the content, but I don't know how to. I tried each of the following ways but none of them work:
connection.body
connection.response.body
connection.env.response.body
# or
r = connection.get
r.body
r.response.body
r.env.response.body
# or
r = connection.get '/'
r.body
r.response.body
r.env.response.body
What is the proper way to get the body?
Note:
In browser, I access https://henry.php directly and browser prompt me a box asking my username and password and I enter them and I can see the content - I can see the details I have is correct and it should work (this is because browser knows how to do basic auth), but I just can't figure out how to do it in code using Faraday.

Answering my own question:
Instead of just:
connection = Faraday.new(url: url) do |conn|
conn.basic_auth(username, password)
end
you should remember to use an adapter:
connection = Faraday.new(url: url) do |conn|
conn.adapter Faraday.default_adapter # make requests with Net::HTTP
conn.basic_auth(username, password)
end
because Faraday is an interface, it does not do the actual work of making connection and request, the adapter does that, so you need it for it to work.
Then, to get ther response body you want, you can just:
response = connection.get
response.body

The Faraday gem comes with a number of plugins (middleware) that make HTTP requests simpler and more customizable. In Ruby, basic authentication might be difficult. Let's have a look at it;
require "faraday"
request_helper = Faraday.new(url: 'example.com') do |builder|
builder.use Faraday::Request::BasicAuthentication, client_key, secret_key
end
# you make HTTP requests using `request_helper` since basic auth is configured
response = request_helper.get('/myendpoit')
You must obtain tokens by proving client and secret keys when using an API such as the Stripe API. We can give client and secret keys as inputs to the Faraday::Request::BasicAuthentication middleware to establish basic authentication using the same approach as before.

You can use:
Faraday.new(...) do |conn|
conn.request :authorization, :basic, 'username', 'password'
end
source: https://lostisland.github.io/faraday/middleware/authentication

For Faraday 1.x this is actually different:
Faraday.new(...) do |conn|
conn.request :basic_auth, 'username', 'password'
end

Related

How to implement authentication on a REST architecture with Parse

I am currently redoing a legacy web application that uses the PHP Parse SDK, and I am in the login authentication part. In the old application, we used $ _SESSION and ParseToken when doing ParseUser::signIn() and ParseUser::currentUser() to check if you have a session with a valid token, however the new application is being made using the REST architecture, where one of the REST concepts is that the server must not keep state, that is, be stateless, and in that case it would be the client that would have to send the necessary data.
When searching the internet and forums, I saw that it is common for developers to authenticate with JWT, where the client would make a request for a server's route and the server would return a token, and through that token authentication would take place.
I even implemented something using Firebase / jwt-php, where the client [Postman] makes a request for the route /login sending via body [username, password] and in case of success, returns the token to be used in secure route requests.
NOTE: Code is as simple as possible, without validation and cleaning just to show the example.
Action /login
$username = $request->getParsedBody()['username'];
$password = $request->getParsedBody()['password'];
$userAuthenticated = ParseUser::logIn($username, $password);
$payload = [
'data' => $userAuthenticated,
'exp' => time() + 3600
];
$token = JWT::encode($payload, $_ENV['JWT_SECRET_KEY']);
echo json_encode(['token' => $token]);
And the protected routes have a middleware that checks if the time has expired, and if this has happened, an exception with a 401 code is launched.
So far so good, authentication works, the problem I don't know if it's right to do it this way, since I need to give a ParseUser::logIn(), just to generate a session in the database and I don't even use it this session to do some authentication, with the exception of operations in the bank, because from what I saw in the documentation, if there is no valid session in the database, the application will return invalid session token error and also when making the request for another route ParseUser::currentUser() returns null, and this may be a problem in the future.
Does anyone have any idea how I can implement authentication for a REST application made in PHP? I appreciate the help !!
I believe the easiest way would be just replacing the default session storage (which uses $_SESSION) to something else that stores the session in, for example, Redis. Reference: https://docs.parseplatform.org/php/guide/#session-storage-interface
But the way you are doing should also work. You will only have to make sure that, every time that a request comes, you will decode the JWT, get the Parse Session token from there, and use ParseUser::become to set the current user: https://docs.parseplatform.org/php/guide/#setting-the-current-user

HTTP Put via php client

I'm writing a small 'app' for a accounting site called Xena.biz
The system has an API that uses oAuth2 to connect to. All that I have sorted out - I can perfectly retrieve the information I need. Now I need to submit a PUT string back to Xena - here is where I can't figure it out.
The system is build on a file called XenaClient.php which contains all the authorization calls and all the requests.
Here is an example on how I retrieve information :
<?
require('XenaClient.php');
const CLIENT_ID = 'SECRET';
const CLIENT_SECRET = 'VERY SECRET';
$xenaclient = new XenaOAuth2Client(CLIENT_ID, CLIENT_SECRET);
$xenaclient->setAccessToken($_COOKIE["MaskedCookieName"]);
$ordertask = $xenaclient->fetch('https://my.xena.biz/Api/Fiscal/'.$_GET["fiscal"].'/OrderTask/'.$_GET["orderId"]);
var_dump($ordertask);
?>
But now I want to SEND information via PUT. According to the XenaClient.php script, I should use the command $xenaclient->fetch($url,$parameters);
So this is my shot
require('XenaClient.php');
const CLIENT_ID = 'SECRET';
const CLIENT_SECRET = 'VERY SECRET';
$xenaclient = new XenaOAuth2Client(CLIENT_ID, CLIENT_SECRET);
$xenaclient->setAccessToken($_COOKIE["MaskedCookieName"]);
$xenaclient->fetch('https://my.xena.biz/Api/Fiscal/96946/Order/243936250/Confirmation',array('ConfirmationDate'=>NULL,'ConfirmationReportLayoutId'=>261205291));
?>
This doesn't turn anything back, or doesn't create the wanted effect inside the accounting system. No help to get from Xena themselves, so this is why I ask you guys, hope you can help me.
Heres a few pointers:
The API resource: https://dev.xena.biz
XenaClient.php: https://github.com/EG-BRS/Xena.ExampleApp.PHP/blob/master/XenaClient.php
XenoOAuth2Client::fetch tells you, that the third parameter to the fetch function - although optional - determines the method of the request. Default ist GET (XenaOAuth2Client::HTTP_METHOD_GET), so if you want PUT, you should explicitly provide the appropriate PUT parameter (other methods see the XenoOAuth2Client class constants:
$xenaclient->fetch(
'https://my.xena.biz/Api/Fiscal/96946/Order/243936250/Confirmation',
array('ConfirmationReportLayoutId'=>261205291),
XenaOAuth2Client::HTTP_METHOD_PUT
);
most APIs consume json today, perhaps it's supposed to be json...
$xenaclient->fetch(
'https://my.xena.biz/Api/Fiscal/96946/Order/243936250/Confirmation',
json_encode(array('ConfirmationReportLayoutId'=>261205291)),
XenaOAuth2Client::HTTP_METHOD_PUT
);

Overcome HTTP basic auth when calling WooCommerce API

I‘m trying to call the WooCommerce/Wordpress API, but the online shop that I‘m trying to reach has HTTP Basic Autj turned on. That means, I need to authenticate once to overcome the HTTP authentication and then I need to authenticate a second time using the api key in order to use the api. Is there a possibility to make an api call whilst overcoming two levels of authentication?
The problem is that if I try to authenticate, I use the following code:
$headers = array('Accept' => 'application/json');
$options = array('auth' => array($username, $password));
$request = Requests::get("$url/$api/$model", $headers, $options);
then I get a 401 (unathorised) response from the api, because I didn't send the api token in my request. But if I use the api token and secret instead of the username and password, I don't even get near the api because I don't overcome the http basic authentication.
Thanks for yout help!
From the looks of it, you're having an issue calling your website due to HTTP Basic Auth.
When it comes to authentication on https://your.site, you can connect to https://your.site and enter foo as the user and bar as the password, OR you can connect to https://foo:bar#your.site.
Hope I helped!
I can't comment on your question for clarification as I don't have the rep. So here goes with an answer!
I think the answer is that you will not overcome two levels of authentication in one call. You will likely contact the server first for an access token using your username and password.
Basic authorization usually means that in the initial http request you set the headers to include 'Authorization': 'Basic _______________________' and then in place of the underscores put a long alphanumeric string that is generated by base64-encoding your username and password (that you would log into WooCommerce with I presume) like so: username:password, and including that colon in between.
If I actually base64 encode username:password it comes out to dXNlcm5hbWU6cGFzc3dvcmQK
so when setting your initial http request headers, include:
'Authorization' : 'Basic dXNlcm5hbWU6cGFzc3dvcmQK'
Except base64 encode you're own username and password (separated by the colon!).
Assuming this works, the api may return an access token to you in a few ways. But if you follow the docs you should be able to figure it out from this point.
Again, really not clear on what you're question is exactly but can't comment so I took a shot. Good luck

Authenticating with Google without using redirects

I've been implementing an OAuth login via the Google Identity toolkit in php. I've got as far as getting an authenticated session, the userdata, id, photo etc, which seems to be working more or less ok.
However, I'd like to be able to login using methods that don't rely on redirection on the user's browser (thinking of remote APIs for an application), but bit lost on how to achieve this.
Imagine a request which is something like:
$details = new stdClass();
$details->secret = $config->secret;
$details->client_id = $config->client_id;
$details->app_name = 'my awesome oauth app';
$details->login = array();
$details->login['email'] = 'some google account email # example.com';
$details->login['password'] = '1234';
$token = $this->do_auth($details);
if($token) {
// do stuff, setup cookies, insert token in session table etc
}
I'm using CodeIgniter. Are there any libraries that can do this..? I've seen android apps doing similar things, using custom login forms, so I'm guessing it's achievable in php.
You HAVE to redirect, it's a core essential of the way OAuth works, there is no way around this. That's why there is a redirect_uri parameter.
You only have to do this once though: when the user is logging in and you are requesting an access token. After that, you simply use curl for example to request your data.

Zend HTTP Client password

Im trying to connect from PHP(Zend Framework) code to an aspx Web Service. I need to send via post a few parameters to the page( email, password). I have tried to use Zend_Http_Client, and do this:
$client = new Zend_Http_Client('https://thesiteurl.asmx/Login');
$client->setMethod(Zend_Http_Client::POST);
$client->setAuth($username, $password);
$client->setParameterPost(array('email' => 'email', 'password' => 'password'));
$response = $client->request();
$this->view->response = $response;
where $username, $password are the username and password I use to log in to the web service(it has a pop-up window that asks me for username and password).
This code gives me the unauthorized page. So im asking where am I using the site username and password wrong? How can I use them?
edit:
The Auth is auth-basic.
Edit2:
I talked to the owner of the web service he says that everything is UTF-8 is this a problem, isnt it is a default? If not how do i do that?
You could check if a referer-header is needed, or it might be that it also needs a cross-site request forgery number. Simply dump the request that is made by your browser when you login and dump the request that your script is generating, compare those and it should work out.
For the browser-request dump you could use livehttpheaders plugin for firefox.
Depends on what that pop up box really is.
You probably need to study the HTTP Authentication. Currently, Zend_Http_Client only supports basic HTTP authentication. This feature is utilized using the setAuth() method, or by specifying a username and a password in the URI. The setAuth() method takes 3 parameters: The user name, the password and an optional authentication type parameter. As mentioned, currently only basic authentication is supported (digest authentication support is planned).
// Using basic authentication
$client->setAuth('shahar', 'myPassword!', Zend_Http_Client::AUTH_BASIC);
// Since basic auth is default, you can just do this:
$client->setAuth('shahar', 'myPassword!');
// You can also specify username and password in the URI
$client->setUri('http://christer:secret#example.com');
Source.
If this is not an HTTP auth and is somothing else, try to use cURL, wget or linx to see exactly what is happening on the page and now you can simulate it using Zend_Http_Client.
Sometimes you have to send cookies, execute some Js or follow some redirects. Zend_Http_client can do all this things.
have you tried this?
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Socket',
'ssltransport' => 'tls'
);
$client = new Zend_Http_Client('https://thesiteurl.asmx/Login', $config);
$client->setAuth('shahar', 'myPassword!', Zend_Http_Client::AUTH_BASIC);
also I am confused, is this popup a http basic auth, or something that is self designed?
since for basic auth you normally wouldn't send any post params...
the real URL of the site would help very much for finding the solution...
If you can access the servis using browser, use firebug to check the request and response. There might be some other parameters involved, eg cookie.
The best way to tackle these things is by just using the packet sniffer (tcpdump, ethereal, ...) to see what's happening on the line. Then compare the request/response you observe in a working scenario (e.g. from your browser) to the request/reponse which is not working.
This will very quickly reveal the precise difference at the HTTP level. Using this information you can either find out what to fix in your handling of Zend_Http_Client, or find out that Zend_Http_Client doesn't support a particular feature or authentication scheme.

Categories