At my site a user is allowed to sign in with Facebook. When doing that I ask for permission to post to the users feed. This works like a charm.
When signed in, a user is allowed to write a review and when saving the review the user is asked if the user wants to post the review to the users feed on Facebook. Since the post to Facebook should be done after the review is saved in my local db, I understand that I need to perform an authentication serverside and then when I have a token I'm able to POST to eg.
http://graph.facebook.com/10XXXX40308/feed
with
message : "This works"
I have been trying to implement the facebook web login as described here:
The steps are:
When doing 1. in a browser the application behaves accordingly. I get a redirect back from facebook with the MY_VERIFICATION_CODE:
So I try to do it in code like this:
String url = "https://graph.facebook.com/oauth/authorize?client_id="+clientId+"&scope=publish_stream&redirect_uri=http://www.facebook.com/connect/login_success.html";
URL obj = new URL(url);
conn = (HttpURLConnection) obj.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
System.out.println("Request URL ... " + url);
boolean redirect = false;
// normally, 3xx is redirect
int status = conn.getResponseCode();
if (status != HttpURLConnection.HTTP_OK) {
if (status == HttpURLConnection.HTTP_MOVED_TEMP
|| status == HttpURLConnection.HTTP_MOVED_PERM
|| status == HttpURLConnection.HTTP_SEE_OTHER)
redirect = true;
}
System.out.println("Response Code ... " + status);
if (redirect) {
// get redirect url from "location" header field
String newUrl = conn.getHeaderField("Location");
// get the cookie if need, for login
String cookies = conn.getHeaderField("Set-Cookie");
// open the new connnection again
conn = (HttpURLConnection) new URL(newUrl).openConnection();
conn.setRequestProperty("Cookie", cookies);
System.out.println("Redirect to URL : " + newUrl);
}
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer html = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
html.append(inputLine);
}
in.close();
System.out.println("URL Content... \n" + html.toString());
System.out.println("Done");
But what happens is that instead of getting the 302 back I get a 200 back and the login page in code:
It seems that I have missed a step or do not understand the flow.
What I'm trying to accomplish is to implement a similar call like to janrain's:
https://rpxnow.com/api/v2/facebook/stream.publish
where you are allowed to do this.
I guess rtfm is in place here. The user need to authenticate, so what I'm really trying to do here is to bypass the authentication process. This is of course not allowed. So how do you solve this?
When the user authenticates I need to save the access token and the expire time so that I can add that to the request later on.
I think that is the only way.
So in the authentication process I create a regexp:
Pattern pattern = Pattern.compile("access_token=([a-zA-Z0-9]+)&expires=([0-9]+)");
Then in the callback from facebook I extract the token with the regexp:
String accessToken = "";
String expires = "";
Matcher matcher = pattern.matcher(token.trim());
if(matcher.matches()) {
accessToken = matcher.group(1);
expires = matcher.group(2);
} else {
return new JSONObject()
.put("error", "OathBean: accessToken is null");
}
I then call facebook to get the values for the user and return all the values so that I can work with them:
return new JSONObject()
.put("facebookId", facebookId)
.put("firstName", firstName)
.put("lastName", lastName)
.put("email", email)
.put("photo", photo)
.put("accessToken", accessToken)
.put("expires", expires);
Later on when the user wants post a review to facebook. I populate the request and post the review.
Map<String, String> requestData = new HashMap<String, String>();
requestData.put("link",url(newReview));
requestData.put("description", "reviewText");
requestData.put("access_token", credential.getPassword());
String query = createQuery(requestData);
JSONObject result = null;
try {
URL url = new URL("https://graph.facebook.com/"+identifier+"/feed");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.connect();
OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
osw.write(query);
osw.close();
result = new JSONObject(IOUtils.toString(conn.getInputStream()));
}
catch (Exception e) {
log.error("Could not call graph feed to publish for id: "+identifier, e);
}
if(result != null) {
boolean success = StringUtils.isNotBlank(result.getString("id"));
entityManager.persist(new FBPublishEvent(currentUser, newReview, success, result.toString()));
}