2

Users want to use my facebook app for many hours without refreshing the browser.
But token expires in 2 hours. Now I ask users to refresh the page but that's annoying.
I don't want to ask offline access permissions because it will scare some users.

The best solution will be somehow "relogin" and get new token without refreshing the page. Is it possible?

luchaninov
  • 6,792
  • 6
  • 60
  • 75

9 Answers9

3

I would subscribe to the expiry trigger (I think this is authResponseChange), then automate another login check. It won't be a perfect solution as it could trigger a pop up (if they have logged out for example) automatically, which a lot of browsers may block. You could instead, when the token expires, check if they will need to complete a pop up, and display a notification on your page somewhere saying 'Facebook needs your attention to continue', then only launch the pop up from their response, which would stop the pop up being blocked.

FB.Event.subscribe('auth.authResponseChange', function(response) {
  // do something with response
  FB.login(){
    // refresh their session - or use JS to display a notification they can 
    // click to prevent pop up issues
  }
});
Abby
  • 3,169
  • 1
  • 21
  • 40
2

An algorithm to workout on this

  1. Ask for permission from the user
  2. Save the token
  3. Periodically check for an access token is near to expire or not
  4. If its in verse of expiry, embed some dummy iframe, which redirects to the facebook homepage. - Extend auth token without refreshing the page
  5. This should refresh the token. You might need to generate another token or continue with the same. Whatever be required, can be done without refreshing the page.
Community
  • 1
  • 1
acpmasquerade
  • 1,880
  • 1
  • 18
  • 15
  • Actually I addressed the "dummy iframe" idea in my answer. It won't work because Facebook specifically checks for it and prevents it. Your steps 1-3 are correct, but instead of step 4 you must do a top-level redirect. Then the new token will be available and the app can go from there. – Floyd Wilburn Sep 25 '11 at 23:08
1

Have you thought of using ajax? After two hours you will check, if user is still active. If so, you send axax request to URL, where his session details will be updated. example:

$(document).ready(function(){
    setInterval('update_session()', 5500000);
})
update_session(){
    $.post({
        URL: ..., // script to update session on server
        data:{ /* username, password */ },
    })
}

and the server-side just takes username and password from post or and runs relogin.

erazerhead
  • 43
  • 4
  • But how can I update session on server? As far as I understand the only way to update session is to reload the whole page. – luchaninov Sep 16 '11 at 20:50
  • I have to say, that I really don't know, how facebook applications work or what all can be done. But generally the session is identified by some unique session ID, usually stored in a cookie. And everytime the request goes to the server, the cookie is sent with it. Than server looks (usually to cache or file) if the sessionID is registered - if so, there are user details assigned to this ID. So there can be two reasons of session expiration - cookie expires or server cleans it's registry of sessions. First I recommend to try to periodicaly extend cookie expiration time (with javascript). – erazerhead Sep 17 '11 at 08:29
  • If it doesn't work, you'll have to send ajax request with user details (username, password) to some server-side script, which will do re-login and update cookie sessionID. That's it. You do this and you are logged in. Or maybe you could try to change server-side session time, but as I said before, I've got no idea how facebook programming goes and what privileges users have. – erazerhead Sep 17 '11 at 08:32
  • PHP itself cannot login so I cannot use it to extend the session. Instead PHP can get URL where I shall direct user to confirm. And that means page refresh which I try to avoid. – luchaninov Sep 19 '11 at 07:51
  • 3
    I think you would get a big slap on the wrist for asking for their facebook username and password. – Abby Sep 19 '11 at 07:55
  • If you have a use case which needs slow-expiring access_tokens, just ask for the offline_access permission, it's basically what it's for – Igy Sep 20 '11 at 22:19
1

Try acquiring tokens with the offline_access permission.

chwk
  • 441
  • 2
  • 7
1

I presume, guess this is not possible,FB architecture would not allow it. And why is offline_access such a problem!!!!!!...anyway offline_access is the best optimal solution I guess....

Dilip.m
  • 104
  • 1
  • 5
  • The offline_access scope will soon be depreciated as you can see here: http://developers.facebook.com/docs/offline-access-deprecation/ . It would be wise to take this into account if you're developing an application right now. – Marc Hoogvliet Jan 27 '12 at 13:08
0

Unfortunately I believe this is impossible by design (if you mean for it to happen without user intervention). If the user is still logged in to Facebook you can redirect the top-level page to Facebook and it will bounce you right back with a new code (as it sounds like you are doing already), but that is only possible because of the Facebook cookie that it can check. If you try to do anything from your server, it will be rejected because that cookie will not accompany the request. Same goes for trying to make a call to facebook from javascript -- since your code is running in a different domain, the cookie will not accompany the call and Facebook will reject it. The only way that Facebook can even know who the user is, and that they are still logged in, is to see that cookie. And the only way that can happen is if the browser itself is redirected to the facebook.com domain.

It's worth mentioning also that Facebook has blocked the only logical workaround, i.e. loading the oauth url in an iframe. If you try it you will see that they detect the page is being loaded in an iframe and output a page with a link on it which does a top-level redirect to break out of the frame. So not only does this approach not work, it's clear that Facebook has specifically made it impossible as part of their architecture.

Edit: If what you mean to do is not avoid the refresh altogether but just have it happen automatically when a new token is needed, you can do something like this:

$status=0;
$data=@file_get_contents("https://graph.facebook.com/me?access_token=$token");
foreach ($http_response_header as $rh) if (substr($rh, 0, 4)=='HTTP') list(,$status,)=explode(' ', $rh, 3);
if ($status==200)
  {
  //token is good, proceed
  }
else
  {
  //token is expired, get new one
  $fburl="http://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=".urlencode('http://apps.facebook.com/yourapp/thispage.php');
  echo "<html>\n<body>\n<script>top.location='$fburl';</script>\n</body>\n</html>\n";
  exit;
  }

This is assuming you have something before this code that will process a signed_request parameter if it is present and assign a value to $token (either explicit code of your own or the appropriate SDK entries). The shown code can then be used anywhere you need to check if $token is still valid before proceeding.

Floyd Wilburn
  • 1,852
  • 2
  • 13
  • 6
  • But you can open some game in the morning, "accept" some gifts in the evening and they will be deleted immediately from your notifications. So they prolong access tokens somehow and don't push me to refresh. I want to do the same in my app. – luchaninov Sep 19 '11 at 09:47
  • Perhaps I'm not fully understanding what you are trying to do. I thought you meant that your users would only be interacting with your app canvas and thus you would only have the original token you got when they first opened it, which would expire in two hours. It sounds like now you are describing a user being "returned" to your app by interacting with the Facebook frame? – Floyd Wilburn Sep 19 '11 at 10:20
  • I want user that came 10 hours ago and has not refreshed browser to be able to send gifts to his friends. But how is it possible in other Facebook games if token is expired after 2 hours? – luchaninov Sep 19 '11 at 13:06
  • When you say "has not refreshed browser" do you mean just that the user has not done anything manually (like actually clicking the refresh button)? Or that you don't want your app to have to do a total page refresh? Again I think I must not be understanding what you really want, I thought you were saying you wanted to "renew" the token but without doing a top-level redirect. Let's rephrase--in your current setup what happens when the token is expired, and what should happen instead? – Floyd Wilburn Sep 19 '11 at 15:57
  • Player enters the game, clicks some buttons. Goes somewhere for 3 hours, browser remains open. Then he clicks "Accept gift", server tries to delete notification from Facebook but Facebook tells "Token has expired". Other games somehow manage to remove notifications. – luchaninov Sep 20 '11 at 07:39
0

If you get the access_token without specifying any expiry to them they will not expire .. atleast not till the time user either changes his Fb credentials or de registers your application ..

mjs
  • 657
  • 7
  • 14
  • that is if offline_access is in the scope during access token's creation, he does not want to use that scope, so the access token expires.. – Dilip.m Sep 23 '11 at 14:01
0

I presume you are using the iframe signed_request parameter to get your access token. One method of achieving what you require is to use the oAuth 2.0 method of aquiring an access token. This is more prolonged in the first instance; your server and Facebook's have to exchange credentials which can be slow, but it means that you will be given a code that can be exchanged for an access token regularly, meaning your server can maintain the session periodically (probably from an ajax call from the client). You would then pass this new access_token to the client, and use it in your dialog call for your requests (gifts).

Hope that helps.

Spabby

GeeH
  • 563
  • 4
  • 14
  • Thanks. I'll switch to oAuth 2.0 soon and check if it helps. – luchaninov Sep 22 '11 at 11:45
  • Although I've never tested it to see, according to the documentation you can't keep using the same code to get new tokens. If you have to get a new code, you're right back in the same boat. – Floyd Wilburn Sep 22 '11 at 19:22
0

Have a look at https://developers.facebook.com/docs/offline-access-deprecation/#extend_token

basically you extend the token with

https://graph.facebook.com/oauth/access_token?             
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN 

that will give you new token with new expiry time (it should be 60d but I'm noticing similar bug like described here https://developers.facebook.com/bugs/347831145255847/?browse=search_4f5b6e51b18170786854060 )

equivalent8
  • 13,754
  • 8
  • 81
  • 109