0

I'm building an Express application that uses the Spotify Web API and I'm using ejs as my view engine. I have one ejs page where you click a button and it calls an endpoint in my Express server which redirects a few times (within the same server) using res.redirect() before finally landing on an endpoint that calls https://accounts.spotify.com/authorize like this

res.redirect('https://accounts.spotify.com/authorize' +
      '?response_type=code' +
      '&client_id=' + process.env.SPOTIFY_CLIENT_ID +
      (scopes ? '&scope=' + encodeURIComponent(scopes) : '') +
      '&redirect_uri=' + encodeURIComponent(process.env.SPOTIFY_REDIRECT_URI))

However, in my browser's inspect window, this is the error I get:

Access to XMLHttpRequest at 'https://accounts.spotify.com/authorize?{my params here}' (redirected from 'http://localhost:5000/login') from origin 'http://localhost:5000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

When I make the original call from my ejs page, I use the XMLHttpRequest library and I make the request like so:

xhttp.open("POST", "http://localhost:5000/login", true)
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
xhttp.setRequestHeader('Access-Control-Allow-Origin', '*')
xhttp.setRequestHeader('Access-Control-Allow-Method', 'GET, POST, PATCH, PUT, DELETE, OPTIONS')
xhttp.setRequestHeader('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token')
xhttp.send(`email=${email}&password=${password}`)

I also use the CORS package on my server side code like so:

app.use(cors())

Do I need to enable CORS somewhere else or is there something else that I'm missing completely?

Gautam Jethwani
  • 121
  • 1
  • 2
  • 10

1 Answers1

0

1) You don't have to send Access-Control-* headers when making call from your client (ejs page).

2) The server needs to respond back with Access-Control-* headers to allow CORS. The server also needs to handle 'OPTIONS' request first. Normally, I do this without using the cors middleware like this:

// Enabling CORS
app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "*");

  if (req.method === "OPTIONS") {
    res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH");
    return res.status(200).json({});
  }
  next();
});

It's not a good practice to use * and it will not be allowed in the case where browser needs to accept cookies. But you can use it now to test your api.

The above can also be achieved using cors middleware. The below line:

app.use(cors())

should be added only once before the request is sent to any route/controller. This ensures that the headers required to allow CORS are actually added for every response.

Update: If you want to access the spotify page from your browser, it should be redirected from your client (ejs page). Get the necessary data from your server and use it to redirect from your client.

Raman Kishore
  • 542
  • 2
  • 12
  • Yes I put it before every route – Gautam Jethwani Jun 07 '19 at 06:53
  • Updated the answer. Can you check the response from your server and see if it contains the Access-Control-Allow-Origin header? – Raman Kishore Jun 07 '19 at 06:59
  • So are you saying that I should do either of the two options and not both? – Gautam Jethwani Jun 07 '19 at 07:00
  • Yes. Either of the two options. Not both. – Raman Kishore Jun 07 '19 at 07:05
  • Trying using postman for your api call and check if your server returns the Access-Control-* headers. – Raman Kishore Jun 07 '19 at 07:06
  • I tried using the method you suggested that didn't involve the cors package, it didn't work. I confirmed using the inspect window in chrome that the headers are present in all the requests but I'm still getting the error – Gautam Jethwani Jun 07 '19 at 07:46
  • Actually, in the inspector window, I see two requests to accounts.spotify.com/authorize, the first one has it in the response and request headers but the second one only has it in the request headers. Not sure why – Gautam Jethwani Jun 07 '19 at 07:51
  • If you want to access the spotify page from your browser, it should be redirected from your client (ejs page). Get the necessary data from your server and use it to redirect from your client. – Raman Kishore Jun 07 '19 at 07:54
  • I was redirecting from my browser already. Essentially the ejs page calls my server which redirects it to the Spotify API, but as soon as it redirects the Spotify API, I get the CORS error. I'm just trying to figure out how to get rid of the CORS error even though I use CORS middleware in my server – Gautam Jethwani Jun 07 '19 at 08:29
  • Did you solve it? – MrFisherman Jul 26 '20 at 19:11