Frontend-Path Spotify React App challange

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!

if youre struggling with the authentication, there is a github repository that demonstrates PKCE authorization implementation. it doesn’t need the client id and you can use local storage in browser to store token. It requires several steps but is laid out quite simply for most to follow but it differs from your current implementation.

spotify pkce authorization

spotify pkce authorization flow

hope this helps

Interessting, thanks. I finally managed to get the app running by now.

https://mixtapetunes.netlify.app/

I send it for review to Spotify, so people can log in without beeing whitelisted by me. For now, everyone iteressted to take a look, can send me their Spotify Email and I add it to the whitelist.

1 Like

It looks great love the design! nice job. songs weren’t loading when i searched though. hope you fix it soon

Thanks :slight_smile:

But were you able to log in even without beeing whitelisted? It should actually not be possible according to Spotify.

I was. clicked login and was redirected to spotify login the redirected to the app page. I tried typing. enjoyed the pac man animation as i typed but nothing loaded

Interresting. I guess you can get into the app somehow, but youre not authenticated. Because for that I would need to whitelist you in my Spotify Dashboard. Thats why the search does not work. I have to do some testing I guess and implement something that blocks users from getting in and notify them, that they need to be whitelisted.