Type: New Feature
Affects Version/s: None
Fix Version/s: 1.1.0.M3
Based on the discussion at https://github.com/SpringSource/spring-social/pull/57#issuecomment-5659060.
I've done another sweep of tests and confirmed that the initial token granted to the server side is a long-lived 60-day token. I've also confirmed that calling the aforementioned endpoint with that token does nothing to extend the life of it. (Of course, I really should try again tomorrow to be certain that I'm not just hitting the once-per-day rule...but I have confirmed this in the past.)
It seems that no matter how you end up with a long-lived token (client or server), you're going to need to freshen it up before the 60 days is up and the only way to do that is to go through the authorization flow again (because you can only extend the life of short-lived tokens, not long-lived tokens). Fortunately, this doesn't bother the user because as long as the user has not revoked access, the authorization will still be good and Facebook will immediately redirect back to the app with a new authorization code to exchange for a fresh new access token.
Therefore, whether the token has expired or not, the only way to get a fresh long-lived token after the initial long-lived token (as I understand it) is to go through the authorization flow again.
So, one approach is for you to purposefully take the user through the authorization flow when they first come to your app on a given day and replace the existing connection with the new connection data. Or, you could wait until an ExpiredAuthorizationException is thrown and go through the process then. (Actually, it might be good to do this for any NotAuthorizedException.)
At the moment, there's no support for either case in Spring Social. But here's how it might work (none of this is confirmed...just some sketchings I made):
For the once-per-day case, you could have a servlet filter or Spring MVC interceptor that checks to see when the last refresh was performed and if it hasn't been done yet for that day, store away the original request, take the user through the authorization flow (replacing the existing connection, if any), then bring them back and re-issue the original request.
For the NotAuthorizedException/ExpiredAuthorizationException case (which, btw, would be useful for more than just Facebook), you could have the same filter or interceptor catch the exception, stores away the current request, goes through the authorization flow (replacing the existing connection, if any), then reissues the original request.
These descriptions are purposefully brief so as not to get lost in the details of what should happen. I'm certain that gotchas will be encountered that I haven't thought of.
One potential gotcha is dealing with the transactionality of the original request. Spring's transaction support should rollback anything that can be rolled back when a runtime exception is thrown, but what about non-transactional work that may have been done prior to the exception being thrown? Say, if a tweet was posted to Twitter and then an attempt to post to a person's Facebook wall is met with a NotAuthorizedException...how would that be handled? (Truth is, that's a problem right now and not only with Spring Social, but with any app that could perform non-transactional work before a transaction-killing exception is thrown.)