Search code examples
javascriptnode.jspassport.jsspotifywebapi

Getting 401 when trying to access Spotify web API with access token


I am using Spotify strategy with passport Js for authentication. I then want to use the spotify-web-api-node wrapper library for calls to Spotify for the data. However using the access and refresh tokens gained from the authentication for the subsequent calls is not working out. I am getting a 401 - unauthorised when trying to make a call to Spotify for user specific data.

I tried instantiating the SpotifyWebApiObject with the refresh token and access token. Although I can see in the library it only needs the access token to make the calls. I have tried logging in and out to get new sets of the tokens as well.

passport.use(new SpotifyStrategy({
    clientID: keys.spotifyClientID,
    clientSecret: keys.spotifyClientSecret,
    callbackURL: '/auth/spotify/callback',
    proxy: true
}, async (accessToken, refreshToken, profile, done) => {


    const spotifyId = profile.id;
    const name = profile.displayName;
    const email = profile.emails[0].value;

    console.log(profile.id)
    const existingUser = await User.findOne({ spotifyId: profile.id });

    if (existingUser) {
        let userCredentials = await UserCredential.findOne({ userId: spotifyId });

        if (!userCredentials) {
            return await new UserCredential({ userId: spotifyId, name, accessToken, refreshToken }).save();
        }
        console.log('always get existing user')
        userCredentials.accessToken = accessToken;
        userCredentials.refreshToken = refreshToken;
        return done(null, existingUser);
    }


    const user = await new User({ spotifyId }).save();
    await new UserCredential({ userId: spotifyId, name, accessToken, refreshToken }).save();

    done(null, user);
}));

Once they are stored in the db. I do a look up for the user and use the respective access and refresh tokens.

const getPlaylists = async (user) => {

    let spotifyData = await initiateSpotifyWebApi(user);

    spotifyData.getUserPlaylists(user.spotifyId).then((res) => {
        console.log('response is ===', res)
    }).catch((err) => console.error(err));

}

async function initiateSpotifyWebApi(user) {

    const creds = await UserCredential.findOne({ userId: user.spotifyId });
    const apiCaller = setUpApiObj(creds.refreshToken, creds.accessToken);

    return apiCaller
}

function setUpApiObj(refreshTok, accessTok) {
       const spotifyApi = new SpotifyWebApi({
        accessToken: accessTok,
        refreshToken: refreshTok
    });
    return spotifyApi;
}
getUserPlaylist()

returns an error

{ [WebapiError: Unauthorized] name: 'WebapiError', message: 'Unauthorized', statusCode: 401 }

Any idea why I cannot access the API using this library, the way I am trying?


Solution

  • Couple of things to check. This is just what springs to mind. Correct me if I'm on the wrong track and I'll try to help further.

    1. Check your 'scopes' when you authenticate via Spotify. You need to have the correct scopes to perform different actions on the API. See here: https://developer.spotify.com/documentation/general/guides/authorization-guide/

    2. If you get a 401, use your refresh token (I can see you're storing it) to automatically request, retrieve and overwrite your current AccessToken then perform the request again.