cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Want to learn some quick and useful tips to make your day easier? Check out how Calvin uses Replay to get feedback from other teams at Dropbox here.

Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Attempt to relink Dropbox? keeps recurring

Attempt to relink Dropbox? keeps recurring

Bob S.15
Collaborator | Level 9

I updated my iOS app to use the latest Dropbox SDK over the weekend, and initially it seemed fine.  But now I notice that whenever I go someplace new and reopen my app, it says my Dropbox account is no longer connected and I have to relink it.  Any idea what would cause that to happen?  The app thinks it is linked to an unknown account, until I unlink and then relink it.

 

It is not just a matter of restarting the app. If I terminate and relaunch, then it works.  It seems to be maybe when I switch WiFi networks that triggers it. I'm not sure...

 

Any ideas?

Thanks

Bob

 

 

11 Replies 11

Greg-DB
Dropbox Staff

I'll be happy to help with any issues you're having with the Dropbox API, but I'll need some more information. Please reply with:

  • the name and version number of the platform and SDK you are using
  • the steps to reproduce the issue, including relevant code snippet(s), but don't include any access or refresh token(s)
  • the full text of any error or unexpected output

Bob S.15
Collaborator | Level 9

This is iOS.  According to the Info.plist in the Dropbox framework, it's version 3.6.2.

 

When the app first starts I see this, not sure if it is important:

 

-[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSString' (0xxxxxxx) [/System/Library/Frameworks/Foundation.framework]' for key 'accessToken', even though it was not explicitly included in the client allowed classes set: '{(

    "'DBAccessToken' (0xxxxxxx) [/var/containers/Bundle/Application/xxxxxxx/XXXXXX.app/Frameworks/ObjectiveDropboxOfficial.framework]"

)}'. This will be disallowed in the future.

 

Then a bit later I think from this -[Uploader(Private) connection:didReceiveData:]: self:0xxxxxxxx

 

getCurrentAccount returned2022-07-08 08:37:09.878568-0500 xxxxx[xxx:xxxx] DropboxAuthError[{

    ErrorContent = "expired_access_token/...";

    RequestId = xxxxxxxxxxxxxxxxxxxx;

    StatusCode = 401;

    StructuredAuthError = "<DBAUTHAuthError: 0x282311ae0>";

    UserMessage = nil;

}];

 

Any idea why my access token would expire?

Bob S.15
Collaborator | Level 9

Going over the Github documentation, I suspect this is happening because I still use the long-lived token and had not switched to the V2 version...

 

So ... I switched to using the "newest" method with DBScopeRequest, but now it will no longer authorize even temporarily.  It does not open the Dropbox app or Safari to authenticate anymore.  And when I switched back to the way my code was before, it does the same thing - no longer authorizing.

 

Currently in my code I am checking if [[DBClientsManager authorizedClient]  != nil) then I assume the app is authorized.  But I guess that is no longer true?  It is giving me the "expired access token" error even though DBClientsManager authorizedClient]  != nil.  Is that expected?

 

If I disregard the fact that I supposedly have an authorizedClient and I call authorizeFromControllerV2, it does open the Dropbox app and ask me to Allow, but then gives an error "An error occurred authorizing your app. Please try again."  The only thing in the log at that point is "DBSDKReachability Flag Status" -R"

 

Здравко
Legendary | Level 20

Hi @Bob S.15,

Some time ago long lived access token (the one your application relies on) was deprecated. Such tokens can still be used, if exist, but since recent can NOT more be issued. All new issued tokens are short lived (usually start with "sl.") with validity for 4 hours, at most. Most probably you haven't re-linked your application for long time and since existing long lived access token keep validity, you didn't noticed the change.

 


@Bob S.15 wrote:
I updated my iOS app to use the latest Dropbox SDK over the weekend, and initially it seemed fine. But now I notice that whenever I go someplace new and reopen my app, it says my Dropbox account is no longer connected and I have to relink it. ...

Here you did invalidate your long lived access token (with the update) and that's why your application gets started behave "strange". You know what "strange" means here, I believe. 🙂

To solve this, you have to keep newly introduced refresh token, resulted on initial authentication steps. After that you can use proper form of client instantiation that includes the refresh token. Properly constructed client will take care for the refresh process an you will no more receive something like:


@Bob S.15 wrote:

...

getCurrentAccount returned2022-07-08 08:37:09.878568-0500 xxxxx[xxx:xxxx] DropboxAuthError[{

    ErrorContent = "expired_access_token/...";

....


The above error results from fact that currently your client can't refresh the access token (missing refresh token) and it expires (as can be expected).

Most probably you will need to rewrite your authentication flow to one or other extent. Some time ago offline access was the default. Currently this have to be noted explicitly or you won't receive a refresh token.

Hope this drives you into the right direction.

Bob S.15
Collaborator | Level 9

Thank you - it does help, but I am not sure what I need to do differently?  I did change the flow to the new calls, but do I need to do something specifically to store this new short-lived token?  The GitHub docs don't seem to indicate that...

Здравко
Legendary | Level 20

@Bob S.15 wrote:

...  I did change the flow to the new calls, but do I need to do something specifically to store this new short-lived token?  ...


You don't need to do anything special to store "this new short-lived token" (probably you mean the access token). You can continue using the same way or use any other. The main question is what are you doing to store and reuse the refresh token!!! Are you doing something? 🧐

Greg-DB
Dropbox Staff

@Bob S.15 Thanks for following up with the additional information. As you found, Dropbox is in the process of switching to only issuing short-lived access tokens (and optional refresh tokens) instead of long-lived access tokens. You can find more information on this migration here. (We did send notice of this migration by email, but it sounds like those emails may not have made it to you.)

The 'expired_access_token' error indicates that the call failed because it was made using an expired short-lived access token. Apps can still get long-term access by requesting "offline" access though, in which case the app receives a "refresh token" that can be used to retrieve new short-lived access tokens as needed, without further manual user intervention. (You can find more information in the OAuth Guide and authorization documentation.)

 

The official Dropbox Objective-C SDK will actually handle this for you automatically as long as you set up the authorization flow as documented (that is, using authorizeFromControllerV2 and not authorizeFromController). That is, it will request and store the refresh token for you automatically, in addition to the access token. You don't need to do anything differently to handle those. You should just continue using the supplied authorizedClient and it will handle the refresh process for you.

 

Checking if authorizedClient is nil is still a valid way to see if you have a client, but that doesn't tell you if the stored token is still valid on the server (just like with previous long-lived access tokens which may have been revoked by the user remotely).  If you're getting 'expired_access_token' from an existing authorizedClient, that's likely because it was retrieved using authorizeFromController instead of authorizeFromControllerV2. You would need to unlink and relink with authorizeFromControllerV2 to get a client with a stored refresh token to have that handled automatically.

(For reference, while the creation of new long-lived access tokens is now deprecated, we don't currently have a plan to disable existing long-lived access tokens. If that changes, we will of course announce that ahead of time. That being the case, you can continue using existing long-lived access token(s) without interruption, if you have any. Also, note though that after the change you won't be able to create new long-lived access tokens. While the change began on September 30th 2021, we released it gradually, so you may not have seen your app(s) affected until more recently. Once it applies to your app, it would apply regardless of the "Access token expiration" setting for your app, and that setting may no longer be available for your app.)

 

And regarding the "An error occurred authorizing your app" error, have you migrated your app registration(s) to scopes yet? You can do so via the "Permissions" tab on the app pages on the App Console. You'll need to do so before you can use the new authorizeFromControllerV2 method. (Apologies for the generic error message! I'll ask the team to improve that.)

Bob S.15
Collaborator | Level 9

Thanks for the reply.  I did change to the V2 version of authorizeFromController, but I did not manually Unlink and relink.  Users will not know to do that.

 

If getCurrentAccount failed, should I check to see if the message is "expired access token" and then have my app unlink them?

 

I don't know anything about scopes - this is something I need to do on my Dropbox app control panel?  Before I can use the v2 function at all?  Looking at that link, it looks like my apps already have the permissions they need.  But you're saying I still need to do something on the panel?  Migrate the settings IU guess?  If I do that, will it break things for existing users currently?

 

 

Greg-DB
Dropbox Staff

Yes, if you have any users currently or recently using authorizeFromController, they would be receiving only short-lived access tokens, so you may want to catch that error and prompt them to reauthorize the app using authorizeFromControllerV2 instead in order to get a refresh token.

 

And yes, you can migrate existing app registrations to be "scoped" using the "Permissions" tab of the app's page on the App Console. That's recommended as it allows more granular control over which pieces of API functionality the app can/can't access. That won't affect any existing access tokens or refresh tokens. You can find more information about that here. Alternatively, you can just pass nil to the scopeRequest parameter on authorizeFromControllerV2 instead.

Need more support?
Who's talking

Top contributors to this post

  • User avatar
    Greg-DB Dropbox Staff
  • User avatar
    Bob S.15 Collaborator | Level 9
What do Dropbox user levels mean?