I'm trying to complete Facebook Authentication within a simple JSP page following this example: http://www.sergiy.ca/how-to-implement-facebook-oauth-2.0-app-authorization-process-in-java/
Unfortunately, I'm not very successfull at this point. Your help would be appreciated. As developer of the app, I somehow managed to accept the app and I can see it in my app list. But when I log in as another user, I'm unable to accept the app. The user is not prompted to give access right to the app although the redirect request seems to have been sent to FB. Any help would be much appreciated. My code:
<%# page import="java.util.*,org.apache.commons.codec.binary.*, java.net.*, org.json.simple.*" %>
<html>
<body>
<%
String fbSecretKey = "efqec6fdedd17a64055712dcc7d81f58";
String fbAppId = "116041890091";
String fbCanvasPage = "http://apps.facebook.com/stupidgame/";
String fbCanvasUrl = "http://stupidgame.com:8090/stupidgame/";
String accessToken;
if(request.getParameter("signed_request") != null) {
//it is important to enable url-safe mode for Base64 encoder
Base64 base64 = new Base64(true);
//split request into signature and data
String[] signedRequest = request.getParameter("signed_request").split("\\.", 2);
//parse signature
String sig = new String(base64.decode(signedRequest[0].getBytes("UTF-8")));
//parse data and convert to json object
JSONObject data = (JSONObject)JSONValue.parse(new String(base64.decode(signedRequest[1].getBytes("UTF-8"))));
//check if user authorized the app
if(data.get("user_id")==null || data.get("oauth_token")==null) {
//this is guest, create authorization url that will be passed to javascript
//note that redirect_uri (page the user will be forwarded to after authorization) is set to fbCanvasUrl
response.sendRedirect("https://www.facebook.com/dialog/oauth?client_id=" + fbAppId +
"&redirect_uri=" + fbCanvasUrl + "&scope=publish_stream,offline_access,email");
return;
}
accessToken=data.get("oauth_token")+"";
}else{
response.sendRedirect("https://www.facebook.com/dialog/oauth?client_id=" + fbAppId +
"&redirect_uri=" + URLEncoder.encode(fbCanvasUrl, "UTF-8") +
"&scope=publish_stream,offline_access,email");
return;
}
System.out.println("All set with accessToken:"+accessToken);
%>
</body>
</html>
Since you app is running in an iframe "response.sendRedirect" only redirects the iframe and the auth dialog needs to be the whole page.
Replace:
response.sendRedirect(...)
with:
%><script language="JavaScript"> top.location.href = "<%=auth_url%>"; </script> <%
Or something similar and it should work.
The javascript should be similar to the php docs https://developers.facebook.com/docs/authentication/
Related
I'm using TRESTClient/THTTPBasicAuthenticator/TRESTRequest/TRESTResponse to get data from a server.
With response Ok (200), instead of receiving JSON data, I get as content this:
<script type="text/javascript">
<!-- function redirectToIndex()
{
var adresse = window.location.pathname.split('/');
var httpURL = window.location.hostname + "/" + "app"; // redirect to root
var httpsURL = "https://" + httpURL;
window.location = httpsURL;
}
redirectToIndex(); //-->
This is when TRESTRequest.Accept is empty. If I change for TRESTRequest.Accept:= 'application/json', I get an error
406 - Not Acceptable
Could you tell me what's wrong with my request?
Thank you Peter.
I managed to clarify with the API support the BASIC Authentication using the correct login/password . The documentation was inaccurate.
Access is now working as expected.
I'm developing a simple login form (security is not a problem) where the user visits the page login inserts username and password and press send that POST these information to the page check.
Page check checks credential and, if everything is OK, creates cookie and redirect to page home, otherwise redirects to page login.
I use the following redirect:
return Response.temporaryRedirect(new URI("/home")).cookie(cookie, cookie2).build();
This redirects from check (#POST method) to home (#POST method), I just wanna to redirect to home (#GET method).
Important note: I'm a newbie of JAX and what I would like to create is a RESTful service. Are redirects a correct way to implement a REST service?
Now I'll show you small slices of code hoping:
check Page
#POST
#Produces(MediaType.TEXT_HTML)
public Response checkLogin(#FormParam(Login.fieldUsername) String user, #FormParam(Login.fieldPsw) String psw) throws URISyntaxException {
boolean val = db.checkLogin(user, psw);
NewCookie cookie;
NewCookie cookie2;
if(val){
//Valid access + cookie creation
cookie = new NewCookie("username", user);
cookie2 = new NewCookie("hashedPassword", psw);
return Response.temporaryRedirect(new URI("/home")).cookie(cookie, cookie2).build();
} else {
//Wrong login + cookie deletion
cookie = new NewCookie("username", "");
cookie2 = new NewCookie("hashedPassword", "");
return Response.temporaryRedirect(new URI("/login")).cookie(cookie, cookie2).build();
}
}
login page
#GET
#Produces(MediaType.TEXT_HTML)
public Response showLoginForm() throws URISyntaxException{
boolean validCookie = db.checkLogin(username, hashedPassword);
String data = "<form name='Username' action='"+ redirect +"' method='post'><ul>"
+ "<li><label for='"+fieldUsername+"'>Username</label>"
+ " <input type='text' name='"+fieldUsername+"' placeholder='Insert username' required></li>"
+ "<li><label for='"+fieldPsw+"'>Password</label>"
+ " <input type='password' name='"+fieldPsw+"' placeholder='Insert password' required></li>"
+ "<li><input type='submit' value='Login'>"
+ "</li></ul></form>";
if(validCookie){
return Response.temporaryRedirect(new URI(homepage)).build();
}
else {
return Response.ok( showTheForm(data) ).build();
}
}
You can use:
Response.seeOther(redirecttUri).build();
Im new to facebook posting but have had some success with posting offline with a user account but cannot post offline with a company page.
I have created my own "Facebook App" called "Nicks Poster App" via my own personal facebook account. I have granted three permissions (offline_access,read_stream,publish_stream) to the app for both my personal page and my company page.
i did this by following these steps for each account...
Creating the app...
1. Login to facebook with the account you want linked to the app
2. Follow this link http://www.facebook.com/developers/apps.php#!/developers/createapp.php
3. Create your app and take a note of you App Id and your App secret Id.
Giving the correct rights to the app and getting the access_token..
Method 1:
1. Get the account in question to login to facebook
2. However you like, direct the user to this link (replacing <App-Id> with the App Id of the created app) https://graph.facebook.com/oauth/authorize?client_id=<App-Id>&scope=offline_access,read_stream&redirect_uri=http://www.facebook.com/connect/login_success.html
3. Take a note of the result of the “code” querystring.
4. Goto this url (replace “<APP-ID>” with you appId and “<APP-SECRET>” with your apps secret id and “<code>” with the copied code)
https://graph.facebook.com/oauth/access_token?client_id=<APP-ID>&redirect_uri=http://www.facebook.com/connect/login_success.html&client_secret=<APP-SECRET>&code=<code>
5. Copy what you see, minus the expires querystring. That is your access_token.
After i had the access token for both accounts i used this code to make the post.
<!-- FACEBOOK -->
<div id="fb-root"></div>
<script>
(function () {
var e = document.createElement('script');
// replacing with an older version until FB fixes the cancel-login bug
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
//e.src = 'scripts/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
} ());
</script>
<!-- END-OF-FACEBOOK -->
<script>
//initialise
window.fbAsyncInit = function () {
FB.init({
appId: '351023398277068',
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true, // parse XFBML
oauth: true // Enable oauth authentication
});
};
function sendPost(inMessage) {
var opts = {
message: inMessage,
access_token: '<SAVED-TOKEN>'
};
FB.api('/me/feed', 'post', opts, function (response) {
if (!response || response.error) {
alert('Posting error occured');
}
else {
alert('Success - Post ID: ' + response.id);
}
});
}
</script>
When executing the "sendPost" command with the perameter 'Test post', it will work for my personal account (providing i put my access_token in place). This does not work for my company page, and im at a loss as to why(i do put my acess_token in place).
Facebok also havent documented this very well and it makes it hard to make progress, does anyone understand why this doesnt work for company pages?
Thank you in advance.
You can set the "to" parameter to target the page you wish to post to, "manage pages perms will be needed if you wish to post as your page to your page as the application.
<div id="msg"></div>
<script>
// uid is the id of the page or user you wish to post to.
function feedthis2(uid) {
// calling the API ...
var obj = {
method: 'feed',
to: ''+uid+''
};
function callback(response) {
document.getElementById('msg').innerHTML = "Post ID: " + response['post_id'];
}
FB.ui(obj, callback);
}
feedthis2('AnotherFeed'); // to http://facebook.com/anotherfeed
//feedthis2('135669679827333');
</script>
I am building an Facebook IFrame App. I am using the below javascript code to request user to login and allow permissions for the application, after which they are supposed to be redirected to the iframe app. The code works correctly. But, I have two issues with it.
a. as soon as the app loads in IFrame, it redirects to a page (http://www.facebook.com/connect/uiserver.php?app_id=......) and displays a large facebook icon. When I click this icon it redirects to facebook login page. I want my app to redirect to the login page directly instead of showing the inbetween facebook icon page.
b. When the user clicks 'Allow' button for the requested permission in facebook, the page redirects to my main site (http://www.mysite.com) instead of the iframe application(http://apps.facebook.com/myapp).
I have pasted my javascript below, this works with above quirks.
var api_key = 'xxxxxxxxxxxxxxx';
var channel_path = 'xd_receiver.htm';
FB_RequireFeatures(["Api"], function () {
FB.Facebook.init(api_key, channel_path);
var api = FB.Facebook.apiClient;
// require user to login
api.requireLogin(function (exception) {
FB.Connect.showPermissionDialog("publish_stream");
});
});
Help much appreciated.
I have remembered something!
You must use target="_top" in all your links and redirections in a iframe application!
Hope I help you.
Thanks for your answers.
I used the solution posted by McKAMEY(Facebook API: FB.Connect.requireSession issues) with few changes, and it works as intended, without showing the intermediate facebook icon page, and also it redirects after authentication to the iframe app correctly.
I have posted below the working solution in case someone needs it.
var api_key = 'xxxxxxxxxxxx';
var channel_path = './xd_receiver.htm';
var canvas_url = "http://apps.facebook.com/myappxxxx/"// ensure your canvasurl has a '/' at the end!
function Initialize() {
FB_RequireFeatures(["Api"], function () {
FB.Facebook.init(api_key, channel_path);
FB.ensureInit(function () {
FB.Connect.ifUserConnected(
function () {
var uid = FB.Connect.get_loggedInUser();
if (!uid) {
authRedirect();
return;
}
},
authRedirect);
});
});
}
function authRedirect() {
//This is the Sample URL Structure for redirecting to facebook
//http://www.facebook.com/connect/uiserver.php?
//app_id=XXXXXXXXXXXXX&
//next=xxxxxxxxxx_success_url_here_XXXXXXX&
//display=page&
//perms=XXXXXX_comma_seperated_permissions_list_hereXXXXXX&
//fbconnect=1&
//method=permissions.request
window.top.location.href = "http://www.facebook.com/connect/uiserver.php?app_id=" + encodeURIComponent(api_key) + "&next=" + encodeURIComponent(canvas_url) + "&display=page&perms=publish_stream&fbconnect=1&method=permissions.request";
}
Initialize();
Note on redirecting within a frame to the Facebook login page. You have to use javascript to redirect the entire page since the login page passed the X-Frame-Options:DENY header and modern browsers will prevent you from sending the user to the URL if that header is present. Solution is to use javascript::window.top.location = ''; to redirect the whole page
I'm not sure on the middle page between redirection but what does your apps canvas and connect url point to?
The redirection after login should go to that page unless you have this overridden somewhere in your code.
Change the urls in the settings on fb to apps.facebook.com/myapp if that's not what its set to.
You may use the new Facebook Graph API (http://developers.facebook.com/docs/api) to handle authentication. First, you must check if you have the access_token:
$access_token = $_REQUEST['access_token'];
if($access_token != NULL) {
...
}
else {
// the following javascript
}
And the javascript is:
<script type="text/javascript">
top.location.href = '<?= "https://graph.facebook.com/oauth/authorize?client_id=".$appid."&redirect_uri=".$appurl."oauth_redirect" ?>'
</script>
You must have a file oauth_redirect.php like this:
<?php
$code=$_REQUEST['code'];
$url = "http://graph.facebook.com/oauth/access_token?client_id=".$appid."&redirect_uri=".$appurl."oauth_redirect&client_secret=".$appsecret."&code=$code";
$curl = curl_init();
// SET URL FOR THE POST FORM LOGIN
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CUPROPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CUPROPT_SSL_VERIFYHOST, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION ,1);
curl_setopt($curl, CURLOPT_HEADER ,0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER ,1);
// EXECUTE 1st REQUEST (LOGIN)
$response = curl_exec ($curl);
?>
<script type="text/javascript">
top.location.href = '<?= $appurl."?".$response ?>';
</script>
Finally, you can return to your index page (the $appurl variable) and test if the user has permission testing access_token presence.
Hope it helps!
//if user is logged in - do this
function login() {
FB.api('/me', function(response) {
document.getElementById('fb-info-block').innerHTML =
"Welcome, " + response.name + ".<br /><br />" +
"<fb:like href = 'www.whitbreaddesign.com' show_faces = 'false' width = '100' action = 'like' colorscheme = 'light'></fb:like>";
});
}
Can someone tell me how I can add the facebook users profile pic to the above code...After someone connects to my site they will get a Welcome, (their name) to my site....How can I also add there profile picture after Login along with the Welcome note?
I hope by now you've solved this but if not you need to use the access token supplied by the getLoginStatus response.
Check out: http://developers.facebook.com/docs/api
The example links for Users, Pages, Events etc are misleading. If you hover over the links you'll see that Facebook adds "?access_token=%TOKEN%" to each link. That's what you'll need to do.
You function will probably look something like this depending on how you work it.
Hope this helps.
window.fbAsyncInit = function()
{
FB.init({ appId: 'Your App Id', status:true, cookie:true, xfbml:true });
FB.getLoginStatus(function(response){
if(response.session){
/* Fetch Access Token Data Here and set to Global Var */
var access_token = response.session.access_token;
/* Other Init Functions */
}
});
function login()
{
FB.api('/me', function(response){
/* Use Access Token Data Here */
document.getElementById('fb-info-block').innerHTML = (
"Welcome, " + response.name + ".<br /><br />" +
'<br/><img src="https://graph.facebook.com/me/picture?access_token='+ access_token +'"/><br/>'+
"<fb:like href = 'www.whitbreaddesign.com' show_faces = 'false' width = '100' action = 'like' colorscheme = 'light'></fb:like>"
);
});
}
}
<img src="http://graph.facebook.com/me/picture">
Why don't you use fbml tags:
fb:profile-pic and fb:name
(http://developers.facebook.com/docs/reference/fbml/)
And once, you put that FBML inside your div, you may need to call
FB.XFBML.Parse() javascript function.
(It pre-exists as I assume you must have included facebook's javascript by now)
The me shortcut will only work if the person is logged in to fb. You can also use their facebook Id:
<img src="https://graph.facebook.com/220439/picture">