1

I'm trying to return data from our TeamCity server to my React web app using an axios get request. Unfortunately I am not able to enable CORS on the server and always end up with a 401: Unauthorized, or with 'Response for preflight is invalid (redirect)' error.

I have tried to pass the username and password in the headers:

componentDidMount() {
var config = {
    "headers": {
    "username": "username",
    "password": "password"    
  }
}
// Make axios  http request to TeamCity server with authentication headers
axios.get('http://teamcity/app/rest', config)
 .then(res => res.json())
  .then(res => {
    // Transform the raw data by extracting the nested posts
    const projects = res.data.projects;

    // Update state to trigger a re-render.
    // Clear any errors, and turn off the loading indicator.
    this.setState({
      projects,
      loading: false,
      error: null
    });
  })
  .catch(err => {
    // Something went wrong. Save the error in state and re-render.
    this.setState({
      loading: false,
      error: err
    });
  });
 }

I have tried passing the username and password in the url as per this post: How to pass username and password in TeamCity REST API

http://user:pass@server/app/rest/

I have also tried passing the Basic authentication headers from working postman requests.

The request always returns 'XMLHttpRequest cannot load http://teamcity/app/rest. Response for preflight is invalid (redirect)'

I am on the same network as the TeamCity server. Is this possible without enabling CORS?

jo_forty9
  • 11
  • 1
  • 3

1 Answers1

2

You have to enable CORS. Otherwise (even if TeamCity responded with some data) it would be impossible to get access to the response in the browser.

Once you've provided correct origin into the rest.cors.origins internal property, e.g.

rest.cors.origins=http://myinternalwebpage.org.com:8080,https://myinternalwebpage.org.com

you should also enable preflight OPTIONS request support by adding following internal property:

rest.cors.optionsRequest.allowUnauthorized=true

And restart the server.

The docs also suggest to use /app/rest/latest, not /app/rest, and avoid httpAuth prefix.

After that everything should work just fine, e.g.

fetch('http://teamcity:8111/bs/app/rest/latest/builds?count=1', 
{
  headers: {
    'Authorization': 'Basic '+btoa('user:pass'),
    'Accept': 'application/json'
  }
})
.then(r => r.json())
.then(r => console.log(r))
cyberskunk
  • 1,722
  • 20
  • 22
  • It's not just a suggestion to use `/app/rest/latest`: TeamCity requires authentication on the `OPTIONS /httpAuth/app/rest` URLs, which browers don't send, so CORS requests will fail. This was blocking my ability to do `POST` until I stumbled across this answer. Even though I saw this in the docs, I didn't double-check it since `GET` requests were working and so I didn't think this would be a URL-related issue. – gregmac May 01 '19 at 21:59