I’m working fulltime now for the last three weeks on this Spotify ‘Jamming’ Challange. But I don’t get the most important part, the authentication, to work. I’m so unbelievable frustrated, that I’m close to completely trash everything and skip this challange. I also don’t understand why at this point where we just fresh into React and barely into API, we need to do a challange with such an complecated API like Spotify. You can not just build a simple react app like we learned before. You actually need to set up a client and a server (I used express and axios where I have absolutely no clue about at this point).
So at least I found a helpful tutorial on youtube:
How To Build A Better Spotify With React
But even setting up everything exactly like that, it doesn’t work.
So now I have this simple Auth.jsx which (I know should be app) is kinda the entrypoint after the main.jsx:
import React from 'react'
import Login from '../Login/Login'
import App from '../App/App';
const code = new URLSearchParams(window.location.search).get('code');
export default function Auth() {
return code ? <App code={code} /> : <Login />
}
It collects the code from the Spotify Params to get an accessToken. If it has a code, it continues to the App (which is basically my dashboard).
So the first thing in my App is to extract the accessToken with the code:
const accessToken = useAuth(code);
So it calls my useAuth.js:
import { useState, useEffect } from 'react'
import axios from "axios";
const API_URL = 'http://localhost:3001';
export default function useAuth(code) {
const [accessToken, setAccessToken] = useState(null);
const [refreshToken, setRefreshToken] = useState(null);
const [expiresIn, setExpiresIn] = useState(null);
useEffect(() => {
axios.post(`${API_URL}/login`, {
code,
}).then(res => {
setAccessToken(res.data.accessToken);
setRefreshToken(res.data.refreshToken);
setExpiresIn(res.data.expiresIn);
window.history.pushState({}, null, '/');
}).catch(() => {
// window.location = '/';
})
}, [code]);
useEffect(() => {
if (!refreshToken ||!expiresIn) return;
const interval = setInterval(() => {
axios.post(`${API_URL}/refresh`, {
code,
}).then(res => {
setAccessToken(res.data.accessToken);
setExpiresIn(res.data.expiresIn);
}).catch(() => {
window.location = '/';
})
}, (expiresIn - 60) * 1000)
return () => clearInterval(interval);
}, [refreshToken, expiresIn])
return accessToken;
}
So from here it is supposed to go to my server.js:
import 'dotenv/config';
import express from 'express';
import SpotifyWebApi from 'spotify-web-api-node';
import cors from 'cors';
import bodyParser from 'body-parser';
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.post('/refresh', (req, res) => {
const refreshToken = req.body.refreshToken;
console.log('Hi');
const spotifyApi = new SpotifyWebApi({
clientId: process.env.SPOTIFY_CLIENT_ID,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
redirectUri: process.env.SPOTIFY_REDIRECT_URI,
refreshToken
})
spotifyApi.refreshAccessToken()
.then((data) => {
res.json({
accessToken: data.body.access_token,
expiresIn: data.body.expires_in,
})
}).catch(err => {
console.log(err);
res.sendStatus(400)
})
});
app.post('/login', (req, res) => {
const code = req.body.code;
const spotifyApi = new SpotifyWebApi({
clientId: process.env.SPOTIFY_CLIENT_ID,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
redirectUri: process.env.SPOTIFY_REDIRECT_URI
})
spotifyApi.authorizationCodeGrant(code).then(data => {
res.json({
accessToken: data.body.access_token,
refreshToken: data.body.refresh_token,
expires_in: data.body.expires_in
})
}).catch((err) => {
console.log(err);
res.sendStatus(400)
});
});
app.listen(3001)
And this does not work at all. I get into my dashboard, but without accessToken. For some reason the routes to my server never work:
I get this error in the console:
POST
http://localhost:3001/login
[HTTP/1.1 400 Bad Request 147ms]
And this error in the terminal:
[1] WebapiAuthenticationError: An authentication error occurred while communicating with Spotify’s Web API.
[1] Details: invalid_grant Invalid redirect URI.
[1] at _toError (/home/marco/code/marcobaass/walkify/node_modules/spotify-web-api-node/src/http-manager.js:43:12)
[1] at /home/marco/code/marcobaass/walkify/node_modules/spotify-web-api-node/src/http-manager.js:71:25
[1] at Request.callback (/home/marco/code/marcobaass/walkify/node_modules/superagent/lib/node/index.js:905:3)
[1] at /home/marco/code/marcobaass/walkify/node_modules/superagent/lib/node/index.js:1127:20
[1] at IncomingMessage. (/home/marco/code/marcobaass/walkify/node_modules/superagent/lib/node/parsers/json.js:22:7)
[1] at Stream.emit (node:events:527:28)
[1] at Unzip. (/home/marco/code/marcobaass/walkify/node_modules/superagent/lib/node/unzip.js:53:12)
[1] at Unzip.emit (node:events:527:28)
[1] at endReadableNT (node:internal/streams/readable:1345:12)
[1] at processTicksAndRejections (node:internal/process/task_queues:83:21) {
[1] body: { error: ‘invalid_grant’, error_description: ‘Invalid redirect URI’ },
[1] headers: {
[1] date: ‘Fri, 30 Aug 2024 09:42:58 GMT’,
[1] ‘content-type’: ‘application/json’,
[1] ‘x-request-id’: ‘2545910a-9965-4ae6-be58-0a35ea2ce98a’,
[1] ‘set-cookie’: [
[1] ‘__Host-device_id=AQDXhapeD8lAPSmrNXBHxKb-ZfMOF8tCpqoMOV1OUuR96rSaEUtVfxsAI6NvQ6_wxf4HCCLGDfQiFTiHooNX1gQqVCy_NG-Q26s;Version=1;Path=/;Max-Age=2147483647;Secure;HttpOnly;SameSite=Lax’,
[1] ‘sp_tr=false;Version=1;Domain=accounts.spotify.com;Path=/;Secure;SameSite=Lax’
[1] ],
[1] ‘sp-trace-id’: ‘cffa25ea4719f6e9’,
[1] ‘x-envoy-upstream-service-time’: ‘6’,
[1] server: ‘envoy’,
[1] ‘strict-transport-security’: ‘max-age=31536000’,
[1] ‘x-content-type-options’: ‘nosniff’,
[1] ‘content-encoding’: ‘gzip’,
[1] vary: ‘Accept-Encoding’,
[1] via: ‘HTTP/2 edgeproxy, 1.1 google’,
[1] ‘alt-svc’: ‘h3=“:443”; ma=2592000,h3-29=“:443”; ma=2592000’,
[1] connection: ‘close’,
[1] ‘transfer-encoding’: ‘chunked’
[1] },
[1] statusCode: 400
[1] }
This is all way over my head at this point. But I already have put 3 weeks into this. If someone is able to help me, please let me know. I’m very desperate!