Confluence API returns with Curl and from browser but not Fetch

I am attempting to return the contents of a Confluence page in React. I am able to get the data from using a web browser hitting the url of the rest api for the page. https://mysite.com/rest/api/content/107776737?expand=body.view

I am also able to use curl to get the data. But when I use fetch, respone.text returns undefined. I’ve tried about everything I can think of and could use some advice. Below is my code. LOCATION is the address above and TOKEN is my Personal Access Token. I’m not sure why the browser and curl work but fetch doesn’t.

fetch( LOCATION, {
      method: "GET",
      mode: 'no-cors',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + TOKEN,
        'Access-Control-Allow-Origin': '*',
      },
    })
      .then((response) => {
        response.text()
      })
      .then((data) => {
        console.log(data);
      })
      .catch((error) => console.log(error));
  }

Hello @mituller

At a first guess, I’d say you haven’t Base64 encoded the username + PAT combination, as described in the REST API documentation.

Curl does automatic Base64 encoding of Basic credentials, but React fetch probably doesn’t.

With curl I didn’t need to add the useremail and used Bearer instead of Basic. I did try using useremail:Personal Access Token and then base64’d. I did the same with my username and with the Personal Access Token only. Both with Bearer and Basic. The results are the same. Note that this is the Personal Access Token and documentation has Api Token for Cloud Confluence.

This is with Confluence server and Authenticated with Active Directory.

Then you must follow the method for using PATs as per the Confluence Server / Data Center REST API Authentication documentation.

Confluence Cloud’s authentication is not the same, hence the reason for the separate documentation and different authentication method for Basic sessions (username + token).

Also, you haven’t said what, exactly, happens when you make the request; are you getting some sort of error message back from the REST API? Does your chosen authentication method work with a test tool like Postman etc? You might just have faulty JS code.

Lastly. browser sessions to the REST API are pre-authenticated via the session cookie, so that’s not an indicator of anything related to PATs.

Anyhow, have fun.

I don’t know about the authentication, but there is a JS error in your code:

     .then((response) => {
        response.text()
      })

Here, you should either add return or remove the curly brackets, otherwise the function inside then() return undefined by default.

     .then((response) => {
        return response.text()
      })

or:

     .then((response) => response.text())
1 Like

Ah yes. Thanks.

Sorry, I did forget to add the error. I thought I added that in the first question. It’s a 404, so it might be something with the instance we have or on the network. Again it is strange that we can access via the web and with curl, but not with fetch. I am not sure what the difference is in how they connect.

Yeah, I can’t seem to figure it out. I have no idea why curl works, but fetch returns a 404. I thought many a proxy, but that doesn’t seem to be an issue. I have no idea what curl does that fetch doesn’t.

A bit late to the party but maybe this will help someone down the line. I encountered a similar issue and it turned out that base64 does not necessaily equal base64:

For some reason, there can be a difference between the base64 encoded output of your terminal and / curl / httpie / etc. and the output that node is producing.

In my case, there was some padding at the end of the base64 encoded string. Removing the padding fixed the issue for me.

Here’s an example javascript snippet:

const buffer = Buffer.from(auth)
const base64 = buffer.toString('base64', 0, buffer.length - 1)

Hope that saves you a bit of time. I know it wasted a lot of mine :slight_smile: