Reputation: 11
I have a next js app where I want to include a section to display my currently-playing track. I have created a separate express app where I complete the authorization process as stated in the spotify documentation, and return my currently playing track as well as the artist and the image successfully when i call my api on the browser.
However, when I try to make a call to it on my next js app I get the following error:
Access to fetch at 'https://accounts.spotify.com/authorize?response_type=code&client_id=3&scope=user-read-private%20user-read-email%20user-read-currently-playing&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fapi%2Fcallback&state=2db5053330e577d4' (redirected from 'http://localhost:8888/api/login') from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. trial.tsx:31
Note: there is no error when I call the api from the browser (I even have it deployed on vercel and it works). There may be an error with the way I am returning it (?).
I have tried adding cors middleware on the server side as well as on the next js api call but nothing seems to work.
This is my /api/login route called login.js:
const login = require('express').Router();
const querystring = require('querystring');
const cors = require('cors');
const corsOptions = {
origin: '*',
credentials: true
}
login.use(cors(corsOptions));
const stateKey = 'spotify_auth_state';
login.get("/", (req, res) => {
const state = generateRandomString(16);
res.cookie(stateKey, state);
// your application requests authorization
const scope = 'user-read-private user-read-email user-read-currently-playing';
res.redirect('https://accounts.spotify.com/authorize?' +
querystring.stringify({
response_type: 'code',
client_id: client_id,
scope: scope,
redirect_uri: redirect_uri,
state: state
}));
});
Here is the callback route (/api/callback):
const callback = require('express').Router();
const querystring = require('querystring');
const request = require('request');
const bodyparser = require('body-parser');
const cors = require('cors');
require('dotenv').config();
callback.use(cors({
origin: 'http://localhost:3000',
credentials: true
}));
callback.use(bodyparser.json());
const stateKey = 'spotify_auth_state';
callback.get('/', (req, res) => {
/* ...callback code to get the authorization token ... */
//here i return the info once i get it
// use the access token to access the Spotify Web API
request.get(options, function(error, response, body) {
console.log(body);
res.set('Content-Type', 'application/json');
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
if (body) {
res.status(200).json({
name: body.item.name,
artist: body.item.artists[0].name,
album: body.item.album.name,
image: body.item.album.images[0].url
});
} else {
res.status(200).json({ name: '', artist: '', album: '', image: ''})
}
});
});
Here is how I am making the api call on next js (pages router):
const apiCall = async () => {
try {
const res = await fetch('http://localhost:8888/api/login', {
method: 'GET',
mode: 'cors',
credentials: 'include',
})
const data = await res.json();
} catch (error) {
console.error('API CALL: Error fetching currently playing song:', error.message);
}
}`
Upvotes: 0
Views: 342
Reputation: 1
Try below code. Make sure variable login
in your code is express app not the Router.
import express from 'express';
import cors from 'cors';
const app = express();
const allowedOrigins = ['http://localhost:3000'];
const options: cors.CorsOptions = {
credentials: true,
origin: allowedOrigins,
};
app.use(cors(options));
In your code origin: "*"
should be origin: ["*"]
.
Upvotes: 0
Reputation: 1052
As you mentioned, it's working on versel but not working on localhost:3000.
Try adding "CORS Unblock" add-on in your browser and test once.
Upvotes: 0