Sending basic authentication information via form - php

I am working on a site that currently uses a basic authentication dialog box login system, that is the type of dialog that you get if you go here: http://www.dur.ac.uk/vm.boatclub/password/index.php
I did not set this system up and am not in a position to easily/quickly work around it, but it DOES work. The issue however is that the dialog box is not very helpful in telling you what login information you have to use (that is which username and password combination), and so I would like to replace it with a form. I had been thinking that this wasn't possible but I wanted to ask in order to find out.
Is it possible to set up an HTML form that sends the data to the server such that it accepts it in the same way that it would using this dialog box? Alternatively is it possible to set up a PHP script that would take normal form data and process it somehow passing it to the server such that it logs in?
Edit: After being told that this is basic authentication I went around and have managed to find a way that works and keeps the user persistently logged in. However, this does not work in internet explorer. The solution was simply to redirect the user to:
http://username:password#www.dur.ac.uk/vm.boatclub/password/index.php
But Internet Explorer removed it due to phishing uses about 3 years ago. Is there a way to use javascript to get the browser to access the site in this way? Or will I have to simply change my UI?

After a fair bit of research I found a way that works in both Chrome and IE, that is all that I've tested it in, but the logic of the code does not suggest it should break anywhere. It is based upon this article:
http://www.peej.co.uk/articles/http-auth-with-html-forms.html
Which is rather in depth but the crux of it is this - on the form submit you make an AJAX request into the basic authenticated folder. AJAX requests can accept username and password information for basic auth, and once the browser has authed once it's authorised in that realm, i.e. it will stay logged in. The previous article does it in pure javascript, so to add something other than simply explaining the link here's a (hopefully fairly transparent) implementation using jQuery:
$(document).ready(function()
{
$('#loginForm').submit(function()
{
var username = $('#usernameInput').val();
var password = $('#passwordInput').val();
$.ajax(
{
'password' : password,
'username' : username,
'url' : 'http://www.website.com/basic-auth-file.php',
'type' : 'GET',
'success' : function(){ window.location = 'http://www.website.com/basic-auth-file.php'; },
'error' : function(){ alert('Bad Login Details');},
}
);
return false;
});
});
This achieved what I wanted, and is relatively simple to understand, however I would implore anyone who wanted this to go out and didn't know about basic auth to go out and do the research!

You can replace it with a form. http://www.dur.ac.uk/vm.boatclub/password/index.php uses basic access authentication.
basic access authentication
What you could do is perform basic authentication via curl
<?php
// HTTP authentication
$url = "http://www.dur.ac.uk/vm.boatclub/password/index.php";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword");
$result = curl_exec($ch);
curl_close($ch);
//echo $result;
?>
Option 1
Proxy everything just echo'ing $result
Option 2
Read headers from $result and if status code != 200 then wrong login information has been entered. User should enter form again. If status code == 200 right credentials have been entered and you should do http basic authentication by sending headers.
header("Authorization: Basic " . base64_encode($username . ":" . $password);
You should not echo any data($result) before sending header else you will get an error
Some quick links:
http://phpsec.org/projects/guide/2.html

Related

How do I add an authentication system for cURL on Firebase?

I'm using Firebase to do a small project and while testing things I discovered I can do cURL requests from any server to my Firebase Database (tested on an online php tester), so I'm considering this is a security flaw for my project and I have been looking for a method to add some kind of password for cURL requests, but I found nothing, at least nothing I could understand. I know firebase have rules to manage who can read or write on my database, but I didnt find something that could filter requests by server or only allow requests that have an special password sent as parameter.
So my question is if there is a way to do something like that I could use on my project so only cURL requests made for me would work.
Here it is one of my cURL requests, in case it helps for resolving my problem.
$url = "https://mydatabase.firebaseio.com/profile/messages/".$_COOKIE['cookiename'].".json";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
Thanks in advance for helping me out.
UPDATE: I found this, I think it could be the thing I need, but Im missing the part where I tell the database to ask for the access token. https://firebase.google.com/docs/database/rest/auth
One solution is to use the Firebase Auth REST API.
In particular, "you can sign in a user with an email and password by issuing an HTTP POST request to the Auth verifyPassword endpoint", see here.
Then you can use the user's uid in your Firebase security rules, in order to protect your database.
You should read and understand the documentation for the REST API. If you want to bypass security rules that would normally apply to web and mobile users, you will need to generate an OAuth token for a service account that has permissions to access your database, and use that in your requests.
If you don't want public access to your database, you will have to set up security rules to limit that. To stop all public access, your rules should be:
{
"rules": {
".read": false,
".write": false
}
}

Facebook Chat Bot - How do I test the welcome message?

My chat bot is working great but I am having trouble debugging the Welcome message functionality because it only shows up when a conversation is initiated (although i'm pretty sure it's not working having tried it on a colleagues phone). How do I reset my chat so it sees me as a new user interacting with it?
This is my welcome PHP Script at the moment
<?php
function webhook() {
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'MYTOKEN') {
echo $challenge;
}
$input = json_decode(file_get_contents('php://input'), true);
$sender = $input['entry'][0]['messaging'][0]['sender']['id'];
$welcomejson = welcomemessage();
welcomesend($json);
function message() {
$json = '{
"setting_type":"call_to_actions",
"thread_state":"new_thread",
"call_to_actions":[
{
"message":{
"text":"Welcome to My BOT!"
}
}
]
}';
return $json;
}
function send($json) {
$url = 'https://graph.facebook.com/v2.6/MYPAGEID/thread_settings?access_token=MYTOKEN';
//Initiate cURL.
$ch = curl_init($url);
//Tell cURL that we want to send a POST request.
curl_setopt($ch, CURLOPT_POST, 1);
//Attach our encoded JSON string to the POST fields.
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
//Set the content type to application/json
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
//Execute the request
$result = curl_exec($ch);
}
Try this:
Open Facebook in a desktop browser and go to the page linked to your messenger bot
Press "Message"
Inside the message popup/discussion choose "Options" (cog icon)
Select "Delete Conversation..." and say "Delete Conversation" in the confirmation prompt
Select "Message" again
Select "Get Started"
Step 4. really deletes the chat history you are having with the page/app so beware.
On desktop, delete the conversation and message the page again.
This will allow you to see the "Get Started" button again, allowing you to test it and your welcome message's functionality.
If you're trying to test the "Messenger Greeting", it's a lot more complicated. See below.
On Desktop the "Messenger Greeting" still will not show up after deleting the conversation. Only the "get started" button reappears. I believe this is a bug that I will be opening up a ticket for most likely.
You can get a similar experience on mobile by deleting the conversation, uninstalling, and reinstalling Messenger, but once again that does not display the Messenger greeting, it only shows the get started button.
Not being able to see the Messenger Greeting again is an issue for developers who are picky about the line-by-line formatting of the Messenger greeting, or who simply need to see it again for a demo of the messenger bot once the greeting has already been seen.
Thankfully, although EXTREMELY painful, there's a workaround. Basically have to re-setup your bot.
Create a new page
NEVER OPEN A MESSAGE WITH THE PAGE/BOT UNTIL STEP 17
Click settings, Messenger, and set your messenger greeting, and press save.
Since that doesn't actually save the toggled setting for some reason, select a different thing from messenger in the sidebar
Reselect Messenger
Turn on the greeting (the message should have saved properly, just not the toggle for whether its on or off)
Change to a different thing in sidebar
Re-select Messenger and double check that the messenger greeting is enabled
Create a new app
Add Messenger as a product
Select the page and copy the page access token
Put the page access token where it is needed in your code
Run your code
Connect to the webhook url with your verify token and all the boxes checked
After webhook connection is successful, subscribe it to your new page
Run your curl command to enable the 'get started' button and your welcome message that will happen after the button is pressed
Open a message with your page, and the Messenger greeting and get started button should appear. YOU GET ONE CHANCE AND THEN YOU'LL HAVE TO REPEAT ALL OF THESE STEPS TO SEE THE GREETING AGAIN.
I believe the toggle on messenger greeting not saving right is also a bug, and I may open a ticket for it.
There is a way to get the welcome screen in Messenger on iOS (at least as of Apr 28th), although it's super annoying. Basically, in addition to deleting the convo, you have to reinstall the app on your phone.
Go to the paged linked to your bot in facebook on desktop
Archive the conversation
Open Messenger on your phone and delete the conversion by swiping right on the cell in the conversation list
Delete Messenger from your phone
Reinstall Messenger from the App Store

Understanding how to publish to a facebook page as a page via a website (app)

I have spent quite some time now trying to establish how, and then the best practise to push some data from my web server to the facebook page created for this purpose.
I have read and understand the process of using access tokens. I have generated an access token for myself, which can be used to post to the page as me ok. I understand this should be used to generate the access token for the page to post as the page which is a ittle more tricky. However, this process involves me logging in and generating an access token which seem inherently bad / inconvenient for an automated process.
For this reason i followed the guides to create an app. I (think I have) linked the app to the page, and thus attempt to push data via the appid and secret from my php code to the page.
When doing this I am presented with this error
{"error":{"message":"(#210) Subject must be a page.","type":"OAuthException","code":210}}
my testing code is this:
$data['picture'] = "http://www.example.com/image.jpg";
$data['link'] = "http://www.example.com/";
$data['message'] = "Your message";
$data['caption'] = "Caption";
$data['description'] = "Description";
$data['access_token'] = $app_token2;
$post_url = 'https://graph.facebook.com/'.$app_id.'/feed';
$url1 = "https://graph.facebook.com/endpoint?key=value&access_token=".$app_id."|". $app_secret ;
echo "<br>$post_url";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $post_url);
//curl_setopt($ch, CURLOPT_URL, $url1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($ch);
curl_close($ch);
echo "$return";
I appreciate using the app for server initiated posting using a permanent (ish) secret is the correct way, but I have found very little documentation on how this process is achieved, hence this question.
Your $post_url is pointing to your $app_id variable, the message says it should point to a page, try getting the id of your page from the /me/accounts endpoint of the graph and putting that in there instead. Though I suspect you will need to use a page access_token (also from the /me/accounts endpoint ) to post to your page
Right, I have worked on this for quite some time and found several errors in my code, but have not answered the question fully.
For starters, you do not post to the appid as mentioned above - its just wrong. The code for posting to userid/feed works when using an access token generated from appid + secret using
$url2 = "https://graph.facebook.com/oauth/access_token?client_id=".$app_id."&client_secret=". $app_secret."&grant_type=client_credentials";
this app access token is valid for as long as your app secret is. Also, if I generate a temporary access code for ME via the graph explorer, parse me/accounts manually and use the page token in
$post_url = 'https://graph.facebook.com/'.$page_id.'/feed';
It posts correctlly as the page.
Secondly, all server side call are required to have appsecret_spoof in them which is generated from
$appsecret_proof= hash_hmac('sha256', $app_token2, $app_secret);
now, according to the facebook docs, a http get call to my userid/accounts should yield page access tokens for all pages the user administers (and also presumably the app).
This can also be called directly by using
$url3 = "https://graph.facebook.com/".$page_id."?fields=access_token";
so when a get is made to this address (including app access token & appsecret_spoof) all i get is 'True' ??
Likewise, when the correct call to
$rob1 = "https://graph.facebook.com/".$user_id."/accounts";
I receive an error
{"error":{"message":"(#10) Application does not have permission for this action","type":"OAuthException","code":10}}
OK permission issue then ! Well the documentation says that only manage_pages is required to retrieve the page token from page_id/accounts, so I trawl through lots of pages and find you can do this by calling this url
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=read_stream
This throws up via facebook gui an accept / deny page for each scope (i ended up adding manage_pages, publish_stream & read_stream to my app) none of which seem to solve the problem !
Right sorted !! FWIW the code above functions correctly, however the way it is setup on facebook leaves a lot to be desired !!!
I began messing with my app and changed its name, type (was an app linked to the page - now isnt) removed perms and also changed the domain name (removed) and all site url details (also removed). this prompted a different error msg which stated the domains did not match. So, I readded just the app domain & site url, saved and all of a sudden my failed code started working !
Having tidied my code up a little I can now see the page access token just fine as I expected. I just wish the facebook guides would cross reference this setup as it is not at all obvious !!!
my working code ended up as thus ($perm_url is used as one time link to allow perms via gui)
$perm_url = "https://www.facebook.com/dialog/oauth?client_id=".$appid."&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=publish_stream,manage_pages,read_stream,status_update";
echo "<br>Test";
$facebook = new Facebook(array('appId' => $appid , 'secret' => $appsecret ,));
$access_token = $facebook->getAccessToken();
$pageinfo = $facebook->api("/".$page_id."?fields=access_token");
$page_access_token = $pageinfo['access_token'];
echo "<br>Holy Grail = $page_access_token ";

Automated Yahoo Mail login with cURL - how?

I am currently attempting to create a page with cURL instructions that does the following:
Take the following link, send a GET request to it, and retrieve the results.
http://login.yahoo.com/config/login?login=xxxxxxx&passwd=yyyyyyyy&.done=http://m.yahoo.com/mail
xxxxx - username
yyyyy - password
Easy, right? Not really. Since the page that is to be returned, is designed to automatically log you in your Yahoo Mail inbox.
I tried with:
<?php
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://login.yahoo.com/config/login?login=xxxxxx&passwd=yyyyyyy&.done=http://m.yahoo.com/mail',
CURLOPT_USERAGENT => 'something-here'
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
echo $resp;
?>
I do get a response, but all it's about is the Yahoo Mail login page. It doesn't actually execute the login and retrieve the related Yahoo inbox.
How would I go about doing that with cURL?
After some extensive testing.. I decided to see as why this was not working and I was interested in #Sammitch's comment that it won't work..
I first tried using my own HTTP Requests class to login and I failed. the response always stayed empty but if I visited the URL from my browser it would work. I turned on the developer tools in Chrome and went to the network section and tried logging in
It seemed that that page posted the data into another page which is
http://login.yahoo.com/config/login_verify2?login=xxxxxx&passwd=yyyyyy&.done=http://m.yahoo.com/mail
After altering my cURL code to work with that URL directly it signed me in.. so this is the solution to your question.. basically the URL you were using did not work and the one that should work is shown above.

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