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.

Discuss Dropbox Developer & API

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

"App Authentication" for App (without tokens). Yet another migration from long lived tokens question

"App Authentication" for App (without tokens). Yet another migration from long lived tokens question

lalomores
Helpful | Level 5
Go to solution

Hi there! I see there have been a lot of questions in the forum on this topic, so I'll just cut to the chase.

My app is made in Meteor (NodeJS) and React. Clients of my app do not need to handle files, just see them. Files are not client related, only related to my Dropbox App and corresponding Dropbox app folder.

 

Checking the Authentication Types the most obvious candidate to replace my long lived token, seems to be "App Authentication": "This type only uses the app's own app key and secret, and doesn't identify a specific user or team". That's perfect. I can safely provide app key and secret in the server exclusively, as the client will never need those. The question is how do I achieve that type of auth?

 

In the js sdk, I only found this example using app key and secret, yet afterwards it goes through the oauth process in the browser anyways. If I don't do that oauth part, I get an error [*] as a result of calling dbx.filesListFolders({ path: '', recursive: true }):

Any ideas what may I be missing?

 

[*]:

"error": {
    "name": "DropboxResponseError",
    "status": 409,
    "headers": {},
    "error": {
        "error_summary": "path/unsupported_content_type/...",
        "error": {
            ".tag": "path",
            "path": {
                ".tag": "unsupported_content_type"
             }
         }
    }
}
1 Accepted Solution

Accepted Solutions

Greg-DB
Dropbox Staff
Go to solution

@lalomores Just like with long-lived access tokens, the user needs to manually authorize the app once to get the refresh token, which can then be stored and re-used without further manual user interaction. In that example, you can see where the SDK returns the refresh token, which is then set on the client, on this line: https://github.com/dropbox/dropbox-sdk-js/blob/main/examples/javascript/simple-backend/code_flow_exa... . You can store and programmatically re-use that 'token.result.refresh_token' value similar to how you would store and programmatically re-use a long-lived access token.

 

The refresh token is used to programmatically retrieve new short-lived access tokens whenever needed, without the user necessarily present. Those new short-lived access tokens that get retrieved automatically are what are used to then make actual API calls, such as filesListFolder (or usersGetCurrentAccount, as in the example).

 

Anyway, while Dropbox and the Dropbox API aren't really designed to be used as a CDN, we do recommend using the official SDK(s) whenever possible for accessing the Dropbox API. And using the app folder access type whenever that works for the use case is also a best practice.

View solution in original post

24 Replies 24

Здравко
Legendary | Level 20
Go to solution

@lalomores wrote:

... Files are not client related, only related to my Dropbox App and corresponding Dropbox app folder.

...

Hi @lalomores,

Hmm... 🤔 Ok, is the application folder for anyone particular application (including your) just a single thing or is it something specific to every one account, which the same application gets link to?! 🤫


@lalomores wrote:

...

Checking the Authentication Types the most obvious candidate to replace my long lived token, seems to be "App Authentication": "This type only uses the app's own app key and secret, and doesn't identify a specific user or team". That's perfect....


In context of findings achieved above (I hope), are you keep thinking "App Authentication" is perfect for your case? 🧐

You have correctly noted that "doesn't identify a specific user or team". That means the Application folder will left out untouchable, because it's an account specific thing, NOT application specific (or not only, at lest)! Application authentication is usable in case of processing resources unassigned to any particular account. The example, you provided above, describes process of assigning application to account. At the beginning only application has to be authenticated because it's still not linked to an account and that's why can't do anything account related. Next user confirmation, the example rely on token from that moment on, not to Application authentication only! That's why access to user related data gets possible.

Application authentication is convenient for use in cases like performing actions on public data like shared links, for example. Like a person receiving a link can see  it and so on, your application can do the same without user authentication. Accessing link doesn't need user authentication in context of account. If there is any kind of additional authentication set by the link issuer, it can be applied too in borders of Application authentication, like human will do.

Again, inapplicable when any kind of account access is need, even when seems negligible! 😉

Hope this clarifies matter.

lalomores
Helpful | Level 5
Go to solution

Hi Здравко, thanks for the quick answer!

Your answer makes me think there might be some fundamental missunderstanding/missinterpretation of what an "App folder" is (from my side).

 

Now, my intentions are to obtain an equivalent effect to that of the long lived token. In my app, that was:

1. My app silently synchronized whatever the Dropbox App Folder had. By synchronize I mean it kept a Mongo table with data about the files names, paths, extensions and created/obtained shared links to each file in the app folder. It did this regularly (say each 15')

2. End users had no idea Dropbox was involved in anyway

3. End users never had to sign in into dropbox. They in fact don't need dropbox accounts to use this app.

4. Whenever an end user searched for a product that had related files (as per their names), they saw the product images or documents (by using the shared links the synchronization made sure exists)

 

The dropbox App Folder was used to:

- Upload product images

- Upload product documents

This would be done either by the owner of the dropbox account (same that created the app in the app console), or by another Dropbox account which the app folder (or a subfolder) has been shared with.

 

I hope this better clarifies my context and intentions.

 

Long lived tokens allowed me to achieve this transparency to the end users.

Is there a way to achieve the same now with the new approach Dropbox is taking?

 

Scott-DB
Dropbox Staff
Go to solution

Hi @lalomores,

 

It sounds like your application needs to have indefinite access to only your account and no other account. For that, you should generate a refresh token and use that to create an access token as needed. For more information getting a refresh token, see the /oauth2/token documentation. Refresh tokens can be used indefinitely without manual interaction like long lived tokens.

 

Also, with app auth, you may only access content which is publicly available (since there is no user or team auth associated with it). So you would need to make a shared link for your folder in order for an app with app auth to access it, otherwise you will need to use user auth with a refresh token.

 

Hope this helps!

lalomores
Helpful | Level 5
Go to solution

Thank you very much @serickson

 

Does the dropbox-sdk-js have a way to obtain the refresh token programmatically without prompting the user? As per your feedback I guess it does, but I'm just not hitting that nail it seems.

 

From the aforementioned example:

const config = {
  fetch,
  clientId: 'jg8wc1hfkvel6ql',
  clientSecret: 'f0i5w4e6mlbbme5',
};

const { Dropbox } = require('dropbox'); // eslint-disable-line import/no-unresolved

const dbx = new Dropbox(config);

 

That way I initialize Dropbox in the server using clientId and clientSecret.

What's next in order to enable this.dbx.filesListFolder ?

 

I'm a bit tangled up looking and playing with the APIs at https://github.com/dropbox/dropbox-sdk-js/blob/main/src/auth.js

 

Also, given the context I've mentioned and my app objectives (basically, to use Dropbox as a kind CDN for my app's images), would you advise a better way to use the Dropbox SDK and App folder to achieve my goals?

 

Thanks a lot.

Greg-DB
Dropbox Staff
Go to solution

@lalomores Just like with long-lived access tokens, the user needs to manually authorize the app once to get the refresh token, which can then be stored and re-used without further manual user interaction. In that example, you can see where the SDK returns the refresh token, which is then set on the client, on this line: https://github.com/dropbox/dropbox-sdk-js/blob/main/examples/javascript/simple-backend/code_flow_exa... . You can store and programmatically re-use that 'token.result.refresh_token' value similar to how you would store and programmatically re-use a long-lived access token.

 

The refresh token is used to programmatically retrieve new short-lived access tokens whenever needed, without the user necessarily present. Those new short-lived access tokens that get retrieved automatically are what are used to then make actual API calls, such as filesListFolder (or usersGetCurrentAccount, as in the example).

 

Anyway, while Dropbox and the Dropbox API aren't really designed to be used as a CDN, we do recommend using the official SDK(s) whenever possible for accessing the Dropbox API. And using the app folder access type whenever that works for the use case is also a best practice.

lalomores
Helpful | Level 5
Go to solution

Oh, I see. I finally understand. Thank you Greg and everybody for your patience.

 

So, in short, what I want is not possible:

1. It is not enough with the client Id and client Secret to programmatically obtain a refresh token.

2. I can't avoid having to go through at least one oauth flow in the client to retrieve a refresh token.

 

If I want to entirely hide the Dropbox oauth flow from my users, I need to do it in a kind-of-hacky way: run it myself either in my app or in an example code as the aforementioned, capturing the generated refresh-token in the server and then using it as a constant for my app's initial setup. Is that right?

 

I think my confusion came from the fact that it didn't quite feel like I was authorizing anything when I generated a long-lived token in the app panel. The same way it didn't feel like I was authorizing the client id and secret when I created the app in the console. It felt more like configuring/setting up.

 

So, to give closure to this matter and if you would be so kind to answer me one more time: Would you say obtaining a refresh token, capturing it and using it as a long-lived token is something that goes against Dropbox's intended/best practices?

 

Otherwise, if Dropbox is actually expecting refresh tokens to be used as long-lived ones, an idea that comes to mind is maybe replacing the "Generate access token" with a "Generate refresh token" in the app console, as this section feels more like configuration than temporary data. And maybe leaving the "Generate access token" (and maybe calling it: Generate short-lived access token) in the API explorer, so it is clear it can be used for a little while just for testing purpose.

 

Thanks a lot for your insights and help.

 

Best regards

 

Greg-DB
Dropbox Staff
Go to solution

Yes, that's correct. The API was designed with the intention that each user would link their own Dropbox account, in order to interact with their own files. While it is technically possible to always connect to just one account for all users, we do not officially support this, for various technical and security reasons.

 

I'll also pass this along as a request for a "Generate refresh token" option, as well as to clarify the token lifetime in the API v2 Explorer, but I can't promise if or when that might be implemented.

lalomores
Helpful | Level 5
Go to solution

Thanks a lot.

Black Jack
New member | Level 2
Go to solution

+1 for "Generate refresh token"

Need more support?
Who's talking

Top contributors to this post

  • User avatar
    maxcastrovidal Explorer | Level 3
  • User avatar
    Greg-DB Dropbox Staff
  • User avatar
    Здравко Legendary | Level 20
  • User avatar
    dwissing Explorer | Level 4
What do Dropbox user levels mean?