As i presumed, i was missing a call to the client-side API to request extended permissions. (ie publish_stream).
I had a simple JavaScript function which was executed as part of the "onlogin" attribute of the FBML Login control.
Previously, i was simply doing a redirect (which would then do a single-sign-on in the server-side code).
Now, im doing this:
function postLogin(targetUrl) {
FB.Facebook.apiClient.users_hasAppPermission('publish_stream', function(result) {
if (result == 0 || result == null) {
FB.Connect.showPermissionDialog('publish_stream', function() { redirectTo(targetUrl); });
} else {
redirectTo(targetUrl);
}
});
}
Translated to english:
// On "Facebook Connect" click (which passes in a redirect URL)
// Check if user has 'publish-stream' permissions
// If they do, just redirect.
// If they dont, show a dialog requesting that permission, then redirect.
Now the server-side Graph API calls all work fine.
So to answer my own original three questions:
- How do i grant extended permissions to publish to the user's wall?
Answer: make use of the client-side JavaScript API function 'FB.Connect.showPermissionDialog' to show the popup, and 'FB.Facebook.apliClient.users_hasAppPermission' to check if they have the permission.
- What is the correct URL for obtaining an OAuth token?
Answer: I still believe it is "https://graph.facebook.com/oauth/access_token?{0}", but "https://graph.facebook.com/oauth/authorize?{0}" might be able to be used for a server-side authentication/authorization process.
- Is there a definitive source for showing how to post to a user's wall using server-side Graph API calls?
Answer: If there was, i wouldnt have to had asked this question - so the answer in short, is no. =)
Advice to anyone starting Facebook Connect work, try to avoid the "Old JavaScript API". Do as much as you can server-side (Graph API), and only use the client-side JavaScript API for the initial handshake (cross domain receiver).
I just dealt with this myself, and here's the part that bit me:
In your step 5... It's possible for a user to register for an account with you entirely separate from their Facebook ID, right? Then some other time they log in with Facebook.... And you just created them a second account and lost their first one.
There needs to be a way to be logged in to your web service, then log in to facebook, and capture the association between the facebook ID and the local account.
Apart from that, your plan sounds solid.
Update: Facebook has added a doc outlining such a scenario HERE
Best Answer
Note 4/16/2011: stream.publish seems to have been deprecated, There's a new way to do this: http://developers.facebook.com/docs/reference/dialogs/feed/
You can use something like this to publish to a wall, the user will need to confirm before it get sent. Don't forget that you'll need to use FB.init and include the JS SDK link.