Discuss Dropbox Developer & API
Hello,
I'm maintaining a Java Desktop application that can use Dropbox to store user data.
I've just discovered that my Dropbox integration doesn't work anymore for new users because of the API breaking change about long-lived tokens (I am not saying it was a wrong decision, security matters ??).
Previously, my application stored the long-lived user token in a preference file in order to prevent the user from having to log in to Dropbox every time he launches the application. My goal is to prevent the user from having to log in to Dropbox every time he launches the application even with short-lived tokens/refresh-tokens.
I understood how to get a refresh token and pass it to the java API through a DbxCredential in DbxClientV2 constructor. I also understood that the client will then refresh the token when needed (when it is about to expire or refused by Dropbox's server).
Nevertheless, I wonder how to know when the access/refresh tokens are refreshed/changed in order to save them again in the preference file.
I found no "token refresh" event I could register (maybe there is no such thing).
The only solution I found is to subclass DbxClientV2 and override its refreshAccessToken method.
Is there is a cleaner way?
After implementation, the solution is not to subclass DbxClientV2. Indeed, the refreshAccessToken method is not called when the client refreshes the token.
On the other hand, we can pass a subclass of DbxCredential to the constructor of DbxClientV2. DbxCredential's public refresh method is called by the client when the token needs to be refreshed. Then, we can intercept the result of the refresh and do what we want with it.
Here is an example:
public class ObservableDbxCredential extends DbxCredential {
...
@Override
public DbxRefreshResult refresh(DbxRequestConfig requestConfig, DbxHost host, Collection<String> scope) throws DbxException {
final DbxRefreshResult refresh = super.refresh(requestConfig, host, scope);
// Insert your code to save the new access token here;
return refresh;
}
}
@Fathzer wrote:...
I found no "token refresh" event I could register (maybe there is no such thing).
...
Hi @Fathzer,
Yes, Dropbox developers involved in SDKs design don't take care for such type of optimization, unfortunately there is no way to do what you mean.
@Fathzer wrote:...
The only solution I found is to subclass DbxClientV2 and override its refreshAccessToken method.
Is there is a cleaner way?
Yes, you can experiment different workarounds. Generally you are on the right way. In addition you don't need to dump credentials every time token needs refresh. You can check is there any credentials update at the end of object live and store updated access token and expiration time if needed.
Good luck.
@Здравко Thanks a lot for your reply.
I've just realized that there's no new refresh token emitted when access token is refreshed. I also read that Dropbox refresh tokens never expires!
So my question is a little bit silly.
I can simply store the refresh token once and reuse it "forever" to create a DbxCredential with a dummy access token already expired. This dummy access token will be automatically refreshed during the first call. It feels like the refresh token is the new long-lived token 😊
@Fathzer wrote:...
I've just realized that there's no new refresh token emitted when access token is refreshed. I also read that Dropbox refresh tokens never expires!
... It feels like the refresh token is the new long-lived token 😊
Hi again @Fathzer,
Yes, that's the idea. 🙂 And it's not just feels, it is actually.
@Fathzer wrote:...
So my question is a little bit silly.
I can simply store the refresh token once and reuse it "forever" to create a DbxCredential with a dummy access token already expired. This dummy access token will be automatically refreshed during the first call. ...
No, you question is not a silly one. It depends what you're trying to achieve. Yes, you can just store the refresh token and use it forever (even more it's mandatory for long term access).
For project that imply application running for long time and Dropbox client object stay along application work, such a way, described by you, is the best choice because there cannot take too much effect of optimization (it's negligible). It's another story if you are preparing command line tools or dynamic plugin for some application. In such cases one client object initialization can become related to only one or few API calls, so removal of every meaningless API call (the one fired to refresh the access token) gonna reflect significantly on application/plugin performance. Many objects may need to be build consecutively again and again in relatively short period if time! But that's a detail that depends on the project you are working on...
Hope this sheds additional light.
After implementation, the solution is not to subclass DbxClientV2. Indeed, the refreshAccessToken method is not called when the client refreshes the token.
On the other hand, we can pass a subclass of DbxCredential to the constructor of DbxClientV2. DbxCredential's public refresh method is called by the client when the token needs to be refreshed. Then, we can intercept the result of the refresh and do what we want with it.
Here is an example:
public class ObservableDbxCredential extends DbxCredential {
...
@Override
public DbxRefreshResult refresh(DbxRequestConfig requestConfig, DbxHost host, Collection<String> scope) throws DbxException {
final DbxRefreshResult refresh = super.refresh(requestConfig, host, scope);
// Insert your code to save the new access token here;
return refresh;
}
}
The way we work is changing. Share and discover new ways to work smarter with Dropbox in our community.
Sound good? Let's get started.Hi there!
If you need more help you can view your support options (expected response time for a ticket is 24 hours), or contact us on Twitter or Facebook.
For more info on available support options, see this article.
If you found the answer to your question, please 'like' the post to say thanks to the user!