You might see that the Dropbox Community team have been busy working on some major updates to the Community itself! So, here is some info on whatā€™s changed, whatā€™s staying the same and what you can expect from the Dropbox Community overall.

Forum Discussion

pvr325i's avatar
pvr325i
Explorer | Level 3
9 months ago

Next.js 14 oAuth 2.0 authorization flow redirect 401 error

Hi first time poster here.

I've got the authorization flow successfully integrated up to the point where the callback url appears in the browser address window, ie:

http://localhost:3000/api/dropboxcallback?code=Ws4_UVwyTaIqwerqwasdfu5BM5xJGSNdXxF_y5V9JGyrs

 

however, this remains static and 'null' appears in the browser.

 

In the browser console,

GET http://localhost:3000/api/dropboxcallback?code=Ws4_UVwyTaIAAAAAAAAu5BM5xJGSNdXxF_y5V9JGyrs 401 (Unauthorized)

 

appears.

 

If the browser address bar is manually executed, ie return is pressed while the address bar is in focus (and within the 5? second time limit), the api/dropboxcallback route is successfully executed and the access token is generated.

I'm following:

https://dropbox.tech/developers/using-oauth-2-0-with-offline-access

https://developers.dropbox.com/oauth-guide

 

and believe it may be necessary to have the 'state' parameter in the initial `https://www.dropbox.com/oauth2/authorize` call.

 

I have this url `http://localhost:3000/api/dropboxcallback` registered as a OAuth 2 Redirect URI in the Dropbox app console.

 

Would anybody be so kind as to shed some light on what I should do next, or suggest where the problem may lie?

 

Any help greatly appreciated.


  • pvr325i wrote:

    ...

    In the browser console,

    GET http://localhost:3000/api/dropboxcallback?code=Ws4_UVwyTaIAAAAAAAAu5BM5xJGSNdXxF_y5V9JGyrs 401 (Unauthorized)

     

    appears.

    ...


    Hi pvr325i,

    You question could get reformatted and redirected back to you: What kind of authorization do you expect on this request and why do you implement such authorization expectation at all? šŸ§

    That request is supposed to be a callback to receive the authentication code - nothing more. At that moment your application is not authorized in any way and the request cannot provide such thing! Granting to access the data (and corresponding authorization) will be the end result of OAuth process (again the end, not before). It's your responsibility to provide some suitable content as response to be shown in browser. šŸ™‹

     


    pvr325i wrote:

    ...

    and believe it may be necessary to have the 'state' parameter in the initial `https://www.dropbox.com/oauth2/authorize` call.

    ...


    The 'state' parameter is a convenient way to pass some context sensitive data either to distinguish different possible calls to the same callback point (if possible) or to prevent possible attacks (or whatever you want). That parameters doesn't anything to do with the issue you have though.

    If you're looking for better protection, a good way is implementing PKCE 'fork' of OAuth. In such a way Dropbox is actively involved in this protection (comparison "code challenge" and "code verifier" just before completion and error if something wrong).

    In all cases (whatever you'll select to use) don't expect authorization (on low HTTP transport protocol level) on any callback - otherwise wouldn't work. If you want, implement your own additional custom protection that wouldn't break the request if you don't like PKCE (or in addition to PKCE).

    Hope this gives direction.

  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff

    pvr325i Š—Š“рŠ°Š²ŠŗŠ¾ is correct; based on that output, that error is coming from your http://localhost:3000 server, so you'd need to check on what it is doing on its /api/dropboxcallback page. For instance, check your server logs and debug the code it is running.

    • pvr325i's avatar
      pvr325i
      Explorer | Level 3

      Thanks @Greg-DB and @Š—Š“рŠ°Š²ŠŗŠ¾ for your replies.

      This is the first time I'm implementing a Dropbox oauth 2.0 authorization flow, so I apologize if my understanding or language is not clear.

      My overall purpose is to have the user sign in to their Dropbox account in the app, for the subsequent purpose of the app then having the authority to interact with the user's Dropbox account on the user's behalf.

      My understanding of the Dropbox oauth 2.0 authorization flow is ultimately it produces an access token which allows the app to use to interact with the user's Dropbox account on the user's behalf.

      This is what I am trying to produce - this access token which will allow the app to interact with the user's Dropbox account on the user's behalf.

      If my understanding of the purpose of the Dropbox oauth 2.0 authorization flow is not correct, I would be grateful if you were able to correct my understanding.

       

      Leaving aside for the moment whether my understanding is correct, what I have been able to achieve so far is the following:

      1. The user indicates that they want to give the app the authority to interact with their Dropbox account on their behalf by clicking a button -> 'Sign in to Dropbox account'
      2. Upon clicking the button, the page is rerouted to -> `https://www.dropbox.com/oauth2/authorize?client_id=${process.env.NEXT_PUBLIC_DROPBOX_APP_KEY}&response_type=code&redirect_uri=${process.env.NEXT_PUBLIC_DROPBOX_REDIRECT_URI}&access_token_type=online`
      3a. The user completes the following Dropbox flow, ie they sign into their Dropbox account, and click the 'Continue' and 'Allow' buttons on the 'Before you connect to this app...' and '[name of app] would like to:' pages respectively

      3b. The Dropbox pages / flow disappears and the browser window goes blank.
      4a. A url similar to the following appears in the browser address bar ('Callback Url'): `http://localhost:3000/api/dropboxcallback?code=Ws4_UVwyTaIAAAAAAAAu87nekOq4KScGOTojU_hhepU`. The browser window is blank, and remains so.
      4b. A GET 401 Unauthorized error appears in the browser console tab:

      4c. The following appears in the network tab of the browser:

      Note the url on the second line begins with dropboxcallback? and not api/dropboxcallback? which is the correct url for the api route.
      4d. If the Callback Url is executed manually (within 5 seconds of it appearing), the api route api/dropboxcallback executes correctly by producing an access token.

      My question is - what is preventing the Callback Url from executing automatically?

      @Greg-DB - you say I 'need to check on what it is doing on its /api/dropboxcallback page'. This page executes correctly - once the url is executed manually. It appears, however, the /api/dropboxcallback page is never reached - something is preventing it from being so - the answer to which likely lies in the reason for the 'Unauthorized' expression in the 401 error. If this assumption is correct, why is it 'Unauthorized'?

      I would be extremely grateful if you were able to help me understand why the Callback Url is being treated as 'Unauthorized'. Perhaps when I understand this I can get the authorization flow to execute automatically.

       

      Any assistance greatly appreciated.

    • pvr325i's avatar
      pvr325i
      Explorer | Level 3

      Hi @Greg-DB and @Š—Š“рŠ°Š²ŠŗŠ¾

       

      Thank you both for your replies.

      This is the first time I am implementing the Dropbox oauth 2.0 authorization flow so I apologise if my understanding or language is not precise.

       

      What I am trying to achieve is for the app to interact with a userā€™s Dropbox account on the userā€™s behalf. I understand that an access token from Dropbox is required by the app in order for the app to achieve this. My understanding is that this access token is produced as a consequence of completing the Dropbox oauth 2.0 authorization flow.

       

      If my understanding is not correct, I would be grateful if you were able to correct it.

       

      Leaving aside for the moment whether my understanding is correct, what I have been able to achieve so far is the following:

       

      1. The user indicates they want to allow the app to interact with the userā€™s Dropbox account on their behalf by clicking a button -> ā€˜Allow Dropbox accessā€™
      2. Upon clicking the button, the page is rerouted to `https://www.dropbox.com/oauth2/authorize?client_id=${process.env.NEXT_PUBLIC_DROPBOX_APP_KEY}&response_type=code&redirect_uri=${process.env.NEXT_PUBLIC_DROPBOX_REDIRECT_URI}&access_token_type=online`;
      3. The Dropbox authorization flow appears. The user is given a choice to click on the ā€˜Continueā€™ and ā€™Allowā€™ buttons on the ā€˜Before you connect to this appā€¦ā€™ and ā€˜[name of app] would like to:ā€™ pages respectively.
      4. If the user clicks on both of these buttons, the Dropbox authorization flow disappears and the browser window goes blank.
      5. A url similar to the following ā€˜http://localhost:3000/api/dropboxcallback?code=Ws4_UVwyTaIAAAAAAAAu9Cdym8LTtUw6RUcHUAP_pQkā€™ appears in the browser address bar (Callback Url)
      6. A GET 401 Unauthorized message appears in the browser console tab
      7.  

      8. A 401 error appears on the second line in the browser network tab
      9.  

      10. If the Callback Url is executed manually, the logic located in the api/dropboxcallback api route executes successfully and an access token is created.

      My question is: why is the Callback Url not executed automatically?

       

      @Greg-DB you say I ā€˜need to check on what it is doing on its /api/dropboxcallback pageā€™ ā€“ this page executes properly and successfully if the Callback Url is executed manually. This page does not appear to be being ā€˜reachedā€™ once the Dropbox authorization flow has finished.

       

      So therefore, why is this so? Why is being treated as ā€˜unauthorizedā€™? If the answer to this question can be determined, then perhaps this will lead to the entire authorization flow executing automatically.

       

      If you were able to provide any assistance as to why the Callback Url is being regarded as unauthorized, I would be very grateful.

       

      Although I made a reference to ā€˜stateā€™ in my original post, I believe I understand the purpose behind this better now and do not believe it forms part of the larger question as to why the Callback Url is being treated as unauthorized. However, I am very happy to be corrected.

       

      I am very grateful for any assistance.

       

       

    • pvr325i's avatar
      pvr325i
      Explorer | Level 3

      So both of my replies seem to have been deleted. I would be grateful if I could understand why that was.

       

      I appear to have solved the issue, with the hurdle being a conceptually different understanding to what the redirect url was meant to represent.

       

      I originally had the redirect url representing an api route in a Next.js 14 app using the app router.

       

      When I had a moment of differentiation, I changed the redirect url to the client side page from which the authorization process had commenced (the clicking of a button) (SOURCE PAGE); although the GET 401 error still appeared in the console, after about 1 second of a blank browser, the SOURCE PAGE did appear, with the url containing the code obtained from the authorization flow. Once this was accomplished, it was a matter of grabbing the code from the url, and then passing this to the api route which swapped this for an access token.

       

      So, I guess, when @Greg-DB said I " need[ed] to check on what it is doing on its /api/dropboxcallback page" in essence he was right, but it took some time to understand what essentially he meant by this - which is, as is my current understanding, this should not be an api route, rather a client-side page from which the code in the url can be obtained, and then sent to an api route to exchange for an access token.

       

      I appreciate there are a few examples of how this oauth process works, with working code examples, but as I presume this is meant to be deployed in a front end application, it would be good to have at least one example of how it is meant to be used in a front end framework (of some language) and not just in node.js.

       

      However I got here, I am very glad it appears to be working.

About Dropbox API Support & Feedback

Node avatar for Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

5,888 PostsLatest Activity: 15 hours ago
326 Following

If you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X or Facebook.

For more info on available support options for your Dropbox plan, see this article.

If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!