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

ancso's avatar
ancso
Helpful | Level 6
3 years ago

Can't get PKCE access token uses javascript fetch request

I am trying to utilize the PKCE in a background script of chrome extension
example shows the following:

 

curl https://api.dropbox.com/oauth2/token \
 -d code=<AUTHORIZATION_CODE> \
 -d grant_type=authorization_code \
 -d code_verifier=<CODE_VERIFIER> \
 -d client_id=<APP_KEY>

 

my code:

 

 var dbxParams = new URLSearchParams({
    client_id:      client_id,
    grant_type:     "authorization_code",
    code:           access_code,
    code_verifier:  code_verifier,
  });
   var url = "https://api.dropbox.com/oauth2/token";

  fetch(url, {
    method: 'POST',
    body: dbxParams
  })
  .then(function(response){
    return response.json()
  })
  .then(function (data) {
    console.log('Request succeeded with JSON response', data);
  })
  .catch(function (error) {
    console.log('Request failed', error);
  });

 

i always get the same reply:

 

{"error_description": "No auth function available for given request", "error": "invalid_request"}
​

 

can you help?

 

  • ancso's avatar
    ancso
    3 years ago

    yes!
    that was the problem
    my apologies I missed these arguments in the request URL

     

    however,
    i am now getting the error 

     

    {error: 'invalid_grant', error_description: 'invalid code verifier'}

     

     

    The URL includes both code_challenge and code_challenge_method
    and looks like:

     

    https://www.dropbox.com/oauth2/authorize?response_type=code&client_id=<client_id>&code_challenge=<code_challenge>&code_challenge_method=S256

     


    and the parameters sent to oauth2/token are:

     

    client_id=<client_id>&grant_type=authorization_code&code=<auth code from dropbox>&code_verifier=<128 char verifier>

     

     

    i also made sure that <code challenge> is a SHA256 hash of <128 char verifier> by testing it at https://emn178.github.io/online-tools/sha256.html

    what am i missing?

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

    ancso Is this the exact code you're running? I just gave it a try and it works for me when I plug in my own client_id, access_code, and code_verifier. (For reference, redirect_uri is optional in this flow, so that shouldn't be an issue.)

     

    The "No auth function available for given request" error should indicate that the necessary authorization information, such as "code", etc., weren't provided (or weren't provided in a correct format that the Dropbox API servers understood). Can you check the network request, using the developer tools, to see what is/isn't being sent?

    • ancso's avatar
      ancso
      Helpful | Level 6

      according to the de tools all parameters are sent
      could it be that one of them is simply of wrong type?
      if so I suppose it will be the calculation of the code_verifier
      for such a small task i did not want to import a library so i have the following code:

      var code_verifier = '';
      var codeChallenge = '';  
      
        /**
         *
         */
        setDropboxCodes(){
          
          var codes = {};
          const base64Encode = (str) => {
            return str.toString('base64')
              .replace(/\+/g, '-')
              .replace(/\//g, '_')
              .replace(/=/g, '');
            }
      
          codeVerifier  = base64Encode(getRandomString(128));
          var code256 = _self.sha256(codes['codeVerifier'])
          .codeChallenge = base64Encode(code256);
      
        }
      
        /**
         *
         */
        getRandomString(length) {
          var randomChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
          var result = '';
          for ( var i = 0; i < length; i++ ) {
              result += randomChars.charAt(Math.floor(Math.random() * randomChars.length));
          }
          return result;
        }

       

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

        Could you elaborate on what you mean when you say "according to the de tools all parameters are sent"? For instance, could you show the request (headers and body) that your client is sending? Be sure to redact any sensitive values themselves though.

         

        If a parameter was being sent in the correct format but had an incorrect value, the API should respond with a different message than the one you're getting.

         

        Also, it's worth mentioning that I'm not running this in the context of a Chrome extension, so that may be contributing to the difference.