Description

Facebook is deprecating offline_access and is now offering a new way to renew expired access tokens. This new approach is not the same as using a refresh token per the OAuth 2 specification, but is similar. This task is a reminder task to look into what implications this deprecation have on Spring Social. At very least, this will have impact on the showcase example which asks for offline_access. It will very likely play into the solution for SOCIAL-263.

I created an app with offline_access deprecation turned on (should be the default for all new apps right now)

At approximately 10:24am CST, I went through the OAuth dance with Facebook and received an access token

The access token was set to expire on March 10, 2012 at 17:20:14 CST

So, it seems that this token has a shelf life of 10 days, 9 hours (the 9 hours seems odd...10 days seems fine)

I was able to use that access token while still signed into FB to get my profile.

I signed out of FB and was still able to use that token to get my profile.

I then exchanged the access token for a new token. Actually, it gave me the same token value with a new expiration. Their documentation says it may or may not be the same token.

The new token is set to expire in 60 days (consistent with their documentation)

A second attempt to renew the token resulted in the same token being returned along with a slightly expired expiration time. In other words, the 2nd renewal attempt had no effect on the expiration time and it just continued to count down. This is consistent with the FB documentation saying that you may only renew once per day.

Craig Walls
added a comment - 29/Feb/12 8:44 AM Just performed a few experiments to see how this new token works:
I created an app with offline_access deprecation turned on (should be the default for all new apps right now)
At approximately 10:24am CST, I went through the OAuth dance with Facebook and received an access token
The access token was set to expire on March 10, 2012 at 17:20:14 CST
So, it seems that this token has a shelf life of 10 days, 9 hours (the 9 hours seems odd...10 days seems fine)
I was able to use that access token while still signed into FB to get my profile.
I signed out of FB and was still able to use that token to get my profile.
I then exchanged the access token for a new token. Actually, it gave me the same token value with a new expiration. Their documentation says it may or may not be the same token.
The new token is set to expire in 60 days (consistent with their documentation)
A second attempt to renew the token resulted in the same token being returned along with a slightly expired expiration time. In other words, the 2nd renewal attempt had no effect on the expiration time and it just continued to count down. This is consistent with the FB documentation saying that you may only renew once per day.

One of the things I find odd is the documentation states the client_secret is required to renew the token. This shouldn't be exposed in JS code--are they expecting you'll do this from a secure server only, or is the secret optional (the docs don't say).

Keith Donald
added a comment - 14/Mar/12 2:24 PM One of the things I find odd is the documentation states the client_secret is required to renew the token. This shouldn't be exposed in JS code--are they expecting you'll do this from a secure server only, or is the secret optional (the docs don't say).

I suggest prioritizing this issue as "major" now, because since today facebook has migrated all apps to the new setting, i.e. without offline_access. You can still manually revert the change, but it would be best if spring social supported the currently official token mechanism.

Bozhidar Bozhanov
added a comment - 03/May/12 6:16 AM I suggest prioritizing this issue as "major" now, because since today facebook has migrated all apps to the new setting, i.e. without offline_access. You can still manually revert the change, but it would be best if spring social supported the currently official token mechanism.

Fair enough, I've updated it to "major". Even though it was set to "minor", know that this one issue has consumed a lot of my time and thought over the past couple of weeks--effectively, treated as a major issue. The documentation at https://developers.facebook.com/roadmap/offline-access-removal/ is a bit difficult to follow (and I've reported that fact to Facebook), especially with regard to the server-side section. I've been trying to get clear answers from Facebook on how it is supposed to work, but no reply.

Meanwhile, from other sources I'm told that the server-side answer is that the token you're initially given will have the 60-day expiration and that the only way to renew it is to go through the authorization flow again; and that the REST API call that they offer for renewing a token is only intended for client-side use (which raises its own questions as Keith pointed out above). That's mostly consistent with the server-side section in the document, but completely inconsistent with the rest of the document where it says you can refresh it every day.

In the absence of any clarification from Facebook on the issue, the only course of action at this point is further testing against Facebook to record the actual behavior. And that testing can be slow given that even if you can refresh the token (which is still debatable) you can only attempt to do so once per day. Any details that anyone in the community can provide will be helpful.

Craig Walls
added a comment - 03/May/12 6:29 AM Fair enough, I've updated it to "major". Even though it was set to "minor", know that this one issue has consumed a lot of my time and thought over the past couple of weeks--effectively, treated as a major issue. The documentation at https://developers.facebook.com/roadmap/offline-access-removal/ is a bit difficult to follow (and I've reported that fact to Facebook), especially with regard to the server-side section. I've been trying to get clear answers from Facebook on how it is supposed to work, but no reply.
Meanwhile, from other sources I'm told that the server-side answer is that the token you're initially given will have the 60-day expiration and that the only way to renew it is to go through the authorization flow again; and that the REST API call that they offer for renewing a token is only intended for client-side use (which raises its own questions as Keith pointed out above). That's mostly consistent with the server-side section in the document, but completely inconsistent with the rest of the document where it says you can refresh it every day.
In the absence of any clarification from Facebook on the issue, the only course of action at this point is further testing against Facebook to record the actual behavior. And that testing can be slow given that even if you can refresh the token (which is still debatable) you can only attempt to do so once per day. Any details that anyone in the community can provide will be helpful.

If it is possible to refresh the token automatically without repeating the user authorization flow then, I think the ideia of handling this in a rest error handling interface is a good one. Would be nice to have this done transparently by spring social. Not only for Facebook, but also for the oficial OAuth2 refresh_token.

Michel Zanini
added a comment - 22/Jun/12 12:33 PM If it is possible to refresh the token automatically without repeating the user authorization flow then, I think the ideia of handling this in a rest error handling interface is a good one. Would be nice to have this done transparently by spring social. Not only for Facebook, but also for the oficial OAuth2 refresh_token.

Craig Walls
added a comment - 22/Jun/12 1:24 PM Indeed it would be nice to be handled automatically. In fact, I have some prototypical work done for such a solution already and it is showing some progress. I'm hoping to wrap that work up soon.

How to handle refresh token automatically without repeat user authorization flow? you said that you have some prototypical work done for such a solution already. Can you please share that asap as facebook gonna remove offline access by Dec 5th 2012?

syed abudhaheer
added a comment - 06/Nov/12 9:39 PM How to handle refresh token automatically without repeat user authorization flow? you said that you have some prototypical work done for such a solution already. Can you please share that asap as facebook gonna remove offline access by Dec 5th 2012?

Yes, I have begun some work on this and it's looking promising, but that work was set aside for some other stuff. I recently have picked it back up and am hoping to have it in a snapshot build and then in a milestone release within the next couple of weeks. That said, I also am focused on some other work regarding tighter integration with Spring Security and that work has a slightly higher priority. Again, I'm shooting to have both of these ready in the next couple of works, but they're both non-trivial bits of work, so I may only get one of them done in time for a M1 release.

With that said, handling of an expired Facebook token is not a new problem starting on December 5th. It's just a new twist on an existing problem: How do I renew a token (from any provider) when that token is no longer valid (for any reason, including expiration or revocation)? For example, today, prior to December 5th, how would you handle the case where the user revoked your token from Twitter? The general answer is that you must go through the authorization flow again. Facebook doesn't offer refresh tokens and the ONLY way to renew an expired token is to go through the authorization flow again-and that's the same solution to dealing with a revoked token. I'm not working on a refresh token solution for Facebook, because no such solution is possible-I am working on automatic handling of invalid tokens, regardless of the provider or reason that they're invalid.

So, back to your question: Yes, I am shooting to get something out prior to December 5th, but I am not making any promises.

Craig Walls
added a comment - 12/Nov/12 8:02 AM Yes, I have begun some work on this and it's looking promising, but that work was set aside for some other stuff. I recently have picked it back up and am hoping to have it in a snapshot build and then in a milestone release within the next couple of weeks. That said, I also am focused on some other work regarding tighter integration with Spring Security and that work has a slightly higher priority. Again, I'm shooting to have both of these ready in the next couple of works, but they're both non-trivial bits of work, so I may only get one of them done in time for a M1 release.
With that said, handling of an expired Facebook token is not a new problem starting on December 5th. It's just a new twist on an existing problem: How do I renew a token (from any provider) when that token is no longer valid (for any reason, including expiration or revocation)? For example, today, prior to December 5th, how would you handle the case where the user revoked your token from Twitter? The general answer is that you must go through the authorization flow again. Facebook doesn't offer refresh tokens and the ONLY way to renew an expired token is to go through the authorization flow again- and that's the same solution to dealing with a revoked token. I'm not working on a refresh token solution for Facebook, because no such solution is possible -I am working on automatic handling of invalid tokens, regardless of the provider or reason that they're invalid.
So, back to your question: Yes, I am shooting to get something out prior to December 5th, but I am not making any promises.

Given that this task is one to research the implications of offline_access deprecation and that I believe that has been explored, I'm closing this task. SOCIAL-328 was created to address the issue directly.

Craig Walls
added a comment - 26/Nov/12 8:02 AM Given that this task is one to research the implications of offline_access deprecation and that I believe that has been explored, I'm closing this task. SOCIAL-328 was created to address the issue directly.

i'm not sure if this is the right place but there is another issue with the accesstokens on facebook. I recently had the problem that I got an ExpiredAuthentication exception, but as i checked the accesstoken it stated valid. It seems that the expiry date is only set initially. Is there a solution for this issue?

Marcel Pater
added a comment - 23/Jan/13 7:35 AM i'm not sure if this is the right place but there is another issue with the accesstokens on facebook. I recently had the problem that I got an ExpiredAuthentication exception, but as i checked the accesstoken it stated valid. It seems that the expiry date is only set initially. Is there a solution for this issue?