Save facebook webpage after user authorization using PHP or Javascript - php

After I login facebook I want to save the content of https://www.facebook.com/pages (no specific page id but the url as you see it, and see suggested Favorite Pages, not pages I like or selected)
I am not trying to obtain the list of the pages the user admins, nor the list of pages they like. So /me/accounts or /me/likes are not useful. I try to obtain all the pages that are added in Facebook, from the last time I visited this url and it suggests them as pages I may like
I am using the example of http://developers.facebook.com/docs/reference/php/ and I take the profile of user I have. So far so good.
I tried to retrieve data using
$facebook->api('/me/pages'),
$facebook->api('/pages'),
$facebook->api('/pages'),
$facebook->api('/id=USER_ID/pages')
and so on but all of them where wrong or by using Graph API pages?id=USER_ID there were Unsupported get/post request.
As Igy said "Suggested pages is not a feature of the API, only the facebook.com interface"
Something else I tried is to save the url with file_get_contents. As urls I used the
ini_set('user_agent','MSIE 4\.0b2;'); //to pretend that I am a browser, it works
http://www.facebook.com/pages?id=USER_ID and
http://www.facebook.com/pages
Although the save is done properly, facebook doesn't recognize the authorization and shows the page I want but for users without login.
I tried javascript in Facebook JavaScript Test Console and after logging in it opens the page recognizing authorization. The code is
<div id="authResponse"></div>
<script>
var
div = document.getElementById('authResponse'),
showAuthRecord = function(response) {
if (!response.authResponse) {
div.innerHTML = '<em>Not Connected</em>';
} else {
var html = '<table>';
for (var key in response.authResponse) {
html += (
'<tr>' +
'<th>' + key + '</th>' +
'<td>' + response.authResponse[key] + '</td>' +
'</tr>'
);
}
div.innerHTML = html;
}
};
FB.getLoginStatus(function(response) {
showAuthRecord(response);
FB.Event.subscribe('auth.authResponseChange', showAuthRecord);
});
window.open('https://www.facebook.com/pages','mywin','left=20,top=20,width=500,height=500,toolbar=1,resizable=0');
</script>
Is there a way to do this in PHP, or Graph API or FQL Query ? Or add in javascript, code to save the page I open ? I haven't found anything yet.

What you are asking for is not possible to obtain through the Facebook Platform. And trying to scrape a page to extract information from is also against Facebook terms:
You will not collect users' content or information, or otherwise
access Facebook, using automated means (such as harvesting bots,
robots, spiders, or scrapers) without our prior permission.
Also you cannot ask the users for their password and login information, please refer to the Facebook Platform Policies:
You must not include functionality that proxies, requests or collects
Facebook usernames or passwords.

Related

Should I use $_GET to dynamically load html?

I am working on a social networking site using PHP, MySQL(PDO), JQuery, and HTML(CSS). I'm working on the profile page right now and I want to determine if the user is on their own page or another's to determine what inputs they'll have. I would like to keep a framework for the profile page and load the respective options rather than having 2 different pages (my profile vs other profile).
I'm learning JQuery and PHP as I go, so right now I am thinking, in JQuery, I can get the $_GET (?username= ) and compare it to the user id of who's logged in, then load the components I need based on that.
Or I determine the user in PHP then run a certain scrip to load the components.
Would on of these ways work, or is there a different/better way to do this?
I don't think you can use $_GET in JavaScript.
Instead, there is a URLSearchParams
const url = new URL('http://domain/path?username=someone');
const username = new URLSearchParams(url.search).get('username)'; // someone
The best security practice is to not rely on anything happening in browser.
This means you should always figure out privileges on the server (on PHP side).
Variant 1 (Simple)
Let's assume you have authenticated the user and have the user as $currentUser and their id as $currentUser->id in PHP.
Now this user wants to view some profile by requesting url "profile?id=555"
So here's (basically) what you do on PHP side:
$requestedProfile = (int)$_GET['profile'];
if ($requestedProfile == $currentUser->id) {
// they want own profile
show_controls_for_own_profile();
} else {
// they want someone else's profile
show_controls_for_other_profile();
}
In this case, jQuery has nothing to do here.
Variant 2 (Separate requests)
Further, let's assume you want to cache the entire profile page to quickly load it into browser, and only after that, ajax-load additional controls associated with user's privileges.
then you have two controller methods (php scripts, whatever) each serving it's own part:
public function showProfile() {
$requestedProfile = (int)$_GET['profile'];
if (profile_exists($requestedProfile)) {
show_the_profile($requestedProfile); // no check here
}
}
The method above would return the generic profile page by its ID (with empty ".controls" element) and on that page, some jquery code would ask the server to return appropriate variant of user-dependent part.
$.ajax('/user-controls.php')
.done(function(response) { $('.controls').html(response); });
Notice it does not tell the server any user ID - server should already know current authenticated user ID from the session!
The second function, same as in the beginning, will return just HTML for the controls:
// Example of getting current profile from server's headers
function get_viewed_profile_id()
{
// url of previous profile page, e.g. http://example.com/profile?id=555
$referer = $_SERVER['HTTP_REFERER'];
$query = parse_url($referer, PHP_URL_QUERY); // id=555
parse_str($query, $params); // ['id' => '555']
return $params['id']; // 555
}
// we should store the authenticated user in session,
// not rely on anything user sends from their browser
$currentUserId = $_SESSION['user']->id;
$requestedProfileId = get_viewed_profile_id();
// now that we know both viewed profile and current user,
// we can compare them
if ($requestedProfileId == $currentUserId) {
// they want own profile
show_controls_for_own_profile();
} else {
// they want someone else's profile
show_controls_for_other_profile();
}
Variant 3 (Passing PHP variable to javascript)
Same as above, but you don't rely on $_SERVER['HTTP_REFERER'], and move some logic to Javascript instead:
Browser asks:
// look up currently browsed profile from current window url
var q = new URLSearchParams(window.location.search);
var controlsURL = '/user-controls.php?viewedProfile=' + q.get('id');
// ask for controls, specifying the currently browsed profile
$.ajax(controlsURL)
.done(function(response) { $('.controls').html(response); });
And server responds with:
function get_viewed_profile_id()
{
return (int)$_GET['viewedProfile'];
}
// we should store the authenticated user in session,
// not rely on anyhting user sends from their browser
$currentUserId = $_SESSION['user']->id;
$requestedProfileId = get_viewed_profile_id();
// now that we know both viewed profile and current user,
// we can compare them
if ($requestedProfileId == $currentUserId) {
// they want own profile
show_controls_for_own_profile();
} else {
// they want someone else's profile
show_controls_for_other_profile();
}
in jquery you can use $.get() with datatype html
You can echo the PHP's GET value in JavaScript. But make sure, without makeItSafe (which you have to define yourself) this code can be exploited to perform cross site scripting attacks:
<script>
var myGlobalUserID = "<?php echo makeItSafe($_GET['userID']); ?>";
</script>
Simply declare one hidden field on page
<input type="hidden" id="username" value="<?php echo $_GET['username'];?>">
Get username value in it.
Then simply fetch that value in jquery
<script>
$(document).ready(function(){
var username = $("#username").val();
if(username == "abc"){
$("#div_one").show();
$("#div_two").hide();
}
});
</script>
using if() condition and hide() , show() method load component which you want to show to user.

Securely exchanging data between iframe and main page

I'm working on a web based CRM system that has limited capabilities to extending it's functionality.
To extend the functionality, I've installed apache with PHP on the same server, from the php code, I have access to the CRM database.
I can run the page served by apache by adding a iframe in the CRM system, grabbing a ID from the URL and passing it to the iframe using the following javascript:
<div id="mydiv">
<script>
function getUrlParam( name, url ) {
if (!url) url = location.href;
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( url );
return results == null ? null : results[1];
}
console.log(window.location.href)
var iframe = document.createElement('iframe');
var html = 'http://192.168.0.2:8000/Map/' + getUrlParam('ID',window.location.href);
iframe.width = 800
iframe.height = 800
iframe.frameBorder = "0"
iframe.src =encodeURI(html);
document.getElementById("mydiv").appendChild(iframe);
console.log('iframe.contentWindow =', iframe.contentWindow);
</script>
</div>
This all works very well, but this aprouch opens up a security issue: To see anything in the CRM system, you need to be logged in.
If someone would know the url/port of the apache server, they can see whatever they like without having to login.
What would be the best way to overcome this security issue without relying on "Security through obscurity" ? Is there a way to check that the iframe source is only loaded when it's indeed a iframe or can I check for cookies from the parent site?
I have no access to the username/password of the loggedin user on the CRM side.
The CRM users only use chrome or firefox by the way.

How can I force a user to view a video before entering website?

I am looking for a solution to load a video for viewing before entering a website.
While viewing the video, there will be a simple registration form with two fields that if submitted will allow skipping the video.
I can check a SESSION variable and redirect to the video page from any page if it was not viewed... the problem is I need somehow to detect a End of Video event or something like that and then set a SESSION variable at the end of the video.
The site is based on Joomla and I can also use a custom PHP solution.
If you are using youtube to show video, you can use youtube api to achieve that.
<div id="player"></div>
<script src="http://www.youtube.com/player_api"></script>
<script>
// create youtube player
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: '0Bmhjf0rKe8',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// autoplay video
function onPlayerReady(event) {
event.target.playVideo();
}
// when video ends
function onPlayerStateChange(event) {
if(event.data === 0) {
alert('done');
}
}
</script>
After event.data === 0 you can tell that video is finished and could redirect back to your page or whatewer.
check this out please...
Detect when an HTML5 video finishes
You just need to put a window.location = 'http://seusite.com';
in the END event ..
this is quite simple, yo do need to provide more information as to where is the source of your video?
im guessing youtube is the way to go, so here are your instructions, which i recommend trying something before asking, because you posted homework here, and not a problem!
you just need to ping the service for the youtube API:
function onPlayerStateChange(evt) {
if (evt.data == 0){
alert (player.getDuration())
}
}
here you can set the session based on some rules, get more info on this api here
https://developers.google.com/youtube/js_api_reference
if you are using your own html5 video with your own player
$('video#test-vid').bind("progress",function(e){
console.log(e.total + ' ' + e.loaded + ' ' + e.lengthComputable );
});
after this a seesion will be true for the particular user instance and you can then let people see the rest of the content.
you can try to store the ip of the user who seen the video before so you wont show it again..
as for the seession well is quite easy and hard to explain here:
basically before setting sessions make sure you have
session_start(); // before thinking of ending or setting sessions
$_SESSION['seen_video'] = $result;

Filling data from one website into another website in php/javascript

I try to filling some data from one website into another website, which both website are not holding in the same server and I have no right to access into the back end of the other website.
For example:
I created a website that will collect the following data from the user
- name
- telephone number
- address
Then I have to pass those data (auto fill-in so that I do not have to manually enter the same data) into the other independent website for user information checking (t0 make sure that the address, telephone and address is the valid data).
Does anyone know how can I do it in php/javascript? Any example or tutorial can show?
I would use JSONP to move data between different domains and use JQuery's getJSON method to make a call to the server. The PHP file should return the data in proper format and the client should be able to read it using JQuery.
Here is a sample:
The server-side PHP code
<?php
header("content-type: application/json");
// Create a generic object.
// Assign it the property 'message' - the feedback message we want the user to see.
$rtnjsonobj->message = "You got an AJAX response via JSONP from another site!";
// Wrap and write a JSON-formatted object with a function call, using the supplied value of parm 'callback' in the URL:
echo $_GET['callback']. '('. json_encode($rtnjsonobj) . ')';
?>
Get data from client
$(document).ready(function() {
$("#jsonpbtn").click(function() {
var surl = "http://www.otherdomain.com/abovepage.php?callback=?";
$.getJSON(surl, function(rtndata) {
alert(rtndata.message);
});
});
});
What your asking is exactly cross-site scripting (XSS). All modern browsers will prevent you from executing any front-end (JS) script on any url which is not in the original domain.
You can try passing GET values into the page and if the devs built handles into their PHP for that, you might be able to populate the fields. I highly doubt this would work because of the massive security hole it would expose.
I don't know what it is your trying to do at the end of the day, but BE VERY CAREFUL. XSS is an exploit and there's a good chance you could get into trouble for it.

How to restrict my app to a single browser tab?

Frankly, it's just causing too much hassle in in v1.0 to have a functionality which requires three form submissions, with $_SESSION session data holding all of the intermediate stuff - only to have a user start an operation, then open a second tab and perform a second operation which tramples over the session data.
I doubt that this is malicious (but can’t discount it). More likely the user starts an operation, gets interrupted, forgets that they started or can’t find the original tab so starts again (then later finds the original tab and tries to complete the operation a second time).
Since I am coding in PHP I can detect the existence of session data on form submission (how would I do that with JS if the user as much as opens another tab – I guess that I would need Ajax – right?).
So, each time I start an operation I check for a flag in session data and if set I reload to a “I’m sorry, Dave. I’m afraid I can’t do that” page, else I set the flag and continue (remembering to clear it at the end of the operation).
I guess that that would work, but:
1) Is it acceptable to restrict browser apps to a single tab/instance?
2) Should I attempt to allow multiple instances in v2.0 ?
Any other comments, help or advice?
A better design would be to avoid storing user interaction state in the session. Put it in hidden form fields or something so that each client request carries its associated state with it. If you're concerned about the user tampering with it, use an HMAC to prevent that, and possibly encrypt it if it contains things the user shouldn't be able to see.
Only state that should be shared between tabs — like the user's login identity, or something like a shopping cart — should be stored in the session.
At most you can is keep a "last requested page" listing in the session file, with flags to indicate that the user shouldn't be allowed to move off it if it's one of these critical form flags. So if you're on form.php and it's a no-move-off one, then any new page loaded should present an "abort or close window" option.
You cannot prevent a user from opening up another tab/window, but you can prevent them from moving elsewhere in your site in those other windows/tabs.
However, consider that this is a very poor user experience. Imagine if Amazon trapped you in the shopping cart page and never let you on to another page without having to actually buy something. Consider updating your code to allow multiple different windows use the same form.
With every browser supporting tabbed browsing it would be a poor user experience to try to restrict browsing to a single tab (you might as well make a desktop app then).
One way you could solve this is by adding a CSRF token to your forms (as a hidden variable), that would be submitted with the request.
CSRF reference
There are many ways to generate the token, but essentially you:
create the token
store in your $_SESSION
output the form with <input type="hidden" name="{token name}"
value="{token value}" />
Then when the form submits you check $_REQUEST['{token name}'] == $_SESSION[{token name}]`.
If that token is different you know it wasn't the form you originally generated and thus can ignore the request until the real form comes in with the correct token.
One thing: if an attacker can figure out how you generate your CSRF tokens then they can forge requests.
Added the below script after I login(say dashboard.php)
<script>
$(document).ready(function()
{
$("a").attr("target", "");
if(typeof(Storage) !== "undefined")
{
sessionStorage.pagecount = 1;
var randomVal = Math.floor((Math.random() * 10000000) + 1);
window.name = randomVal;
var url = "url to update the value in db(say random_value)";
$.post(url, function (data, url)
{
});
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
});
</script>
Added the below script in Header in rest of my pages - 'random_value' is from db for that user
<script>
$(document).ready(function()
{
$("a").attr("target", "_self");
if(typeof(Storage) !== "undefined")
{
if (sessionStorage.pagecount)
{
if('<?=$random_value?>' == window.name)
{
sessionStorage.pagecount = Number(sessionStorage.pagecount) + 1;
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
});
</script>
If I were doing this now, I would probably code a single page AngularJs app (although any form of Js will do).
On start-up, look in local storage for a flag. If set, refuse to start, with suitable message, else set the flag & run the app.
Sure, a malicious user could get around it, since it's not a server-side check, but I would just refuse to support such.

Categories