Work express server and external token with react router

I am serving a react app with an express server. The server talks to spotify’s api. My app was working fine before I implemented routing on reacts side.

var redirect_uri = 'http://localhost:8888/callback'; // Your redirect uri

app.use(express.static(path.join(__dirname, '../build')))

After login into spotify on spotify’s side, and upon successful login, a code is given back in a response query string with the redirect uri. So it would be http://localhost:8888/callback?code=blahblah-gibberish .

A get request is made to the /callback which hits the query string and takes the code from it and makes a post request to spotify’s service at https://accounts.spotify.com/api/token to exchange the code for an access token. That access token then lets us make requests to spotify’s endpoints

app.get('/callback', function(req, res) {

  // your application requests refresh and access tokens

  var code = req.query.code || null;
  var state = req.query.state || null;

    var authOptions = {
      url: 'https://accounts.spotify.com/api/token',
      form: {
        code: code,
        redirect_uri: redirect_uri,
        grant_type: 'authorization_code'
      },
      headers: {
        'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))
      },
      json: true
    };

    request.post(authOptions, function(error, response, body) {
      if (!error && response.statusCode === 200) {

        var access_token = body.access_token,
            refresh_token = body.refresh_token;

        // we can also pass the token to the browser to make requests from there
   res.redirect('http://localhost:3000/#'+
          querystring.stringify({
            access_token: access_token,
            refresh_token: refresh_token
          }));//this allows requests to come from front end from my understanding
       //how do i make requests routes i define in the router. From what i have tried I can only have one 
       //redirect. 
      } 
    });
});
app.listen(8888);

Now for the part thats giving me issues:

res.redirect('http://localhost:3000/#'+
          querystring.stringify({
            access_token: access_token,
            refresh_token: refresh_token
  }));

Before routing, all my components would load under http://localhost:3000. But after routing, when the react app is refreshed any time i make a change, data is no longer being received from the server side. So i am guessing the token needs to be given to every route from reacts side. From my understanding, now that i have implemented routing on the react side…:

<Route path="/playlist" component={Playlist} />
<Route path="/artist/:id" component={ArtistDetail} />

…the token would not be attached to say "localhost:3000/playlist because i only have a redirect for localhost:3000. How do I attach the access token and refresh token to my routes on the react/server side.

How do i get my routes to make requests? Like the server code said: // we can also pass the token to the browser to make requests from there . It passes the token to localhost:3000. How do I get it to pass the token to localhost:3000/whatever.

Hello there. Could you clarify this? Because, it sounds like you are wanting to persist state (non-React) between codebase changes?

Does the app function as a production app? Provided you make no changes to the code, does the app routing work as expected?

This sounds like a different question, because the easy answer would be set up:

useEffect(() => {
  makeRequest();
}, []);

Within each component referenced (Playlist, ArtistDetail)

when my app was under one link: localhost:3000/token, if i made a change in the code, like adding a div, you know reacts automatic reload? Where as you are typing the component seems to keep rerendering? I forgot the term. When my app did not have routing, as I would type, it would reload and also still be getting data from the api.
Now when i type/make a change, no data would be coming in.

Works normally under routing before making change:


No matter which route I went to, data would come in.
After making a change:

The authorization part is missing in the request header
When I said how do i get my routes to make a request, thats the only way I could formulate a question to address my problem. I could be asking the wrong question/ i am thinking of going about this in the wrong way. I dont understand how different routes would work but once you make a change in any component it no longer sends the request token in the header. I dont know where the cut off happens.

This just sounds like a development problem. In which case, you need to either look into preserving state on reload. Something like a fast refresh.

How are you expecting to use the token across different routes?

the components make a request using a javascript wrapper that has helper functions for all spotify endpoints: https://github.com/JMPerez/spotify-web-api-js

So on login, there is a function they provided us with, which upon successful login to spotify will grab the token from the url and the wrapper will use that token to make requests. So in my Tracks component for example, I make a request to spotify’s api like this:

  getMyTracks = () => {
    spotifyApiWrapper.getMySavedTracks({ limit: 50 }).then((response) => {
      this.setState({
        tracks: response.items,
        total: response.total,
      });
    });
  };

On my Login page, the wrapper grabbed the token from the URL when Spotifys service redirects the user back to localhost:3000:

spotifyApiWrapper.setAccessToken(token);

So after login on spotify we are redirected back to my app and the first link you see is
localhost:3000/token.
When you go to the tracks component it becomes localhost:3000/tracks and data is coming in from the endpoint we requested.

I noticed with these routes, it grabbed the token from the login url once and was used in whichever component/route. It makes sense since the wrapper is a dependency for the entire app so the token did not need to be in every url attached to the component for it to grab. But if that is the case, i dont know why a re-rendering on reacts side would cause a cut off.

preserving the state of what?

Well, I might be out of my depth here. A simple solution would be to store the token in a cookie, to use it from there for each route, but I am not sure how preferable this is for your site, in terms of security.