Yates
Yates

Reputation: 87

Query for Spotify's Web API Client Credentials Flow

I'm trying to make a http request based on the documentation at https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow Client Credentials Flow.

I've written

const BASE_URL = 'https://accounts.spotify.com/api/token';
fetch(BASE_URL, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Authorization': 'Basic ' + base64(clientID) + ':' + base64(clientSecret)
            },
            body: JSON.stringify({'grant_type:client_credentials'})
        })

Does this follow what it says to do? I'm confused how to write the body of the post request.

Upvotes: 1

Views: 4128

Answers (3)

hooperdev
hooperdev

Reputation: 951

For me, I'm not sure if this is the case for anyone else, but the spotify api was refusing base64(clientID) + ":" + base64(clientKey), but accepting base64(clientID + ":" + clientKey)

Upvotes: 0

Yates
Yates

Reputation: 87

What I ended up doing which works:

async authorize(){
        let myHeaders = new Headers();
        myHeaders.append("Authorization", `Basic ${my_clientID:clientSecret}`);
        myHeaders.append("Content-Type", "application/x-www-form-urlencoded");

        var urlencoded = new URLSearchParams();
        urlencoded.append("grant_type", "client_credentials");

        const requestOptions = {
        method: 'POST',
        headers: myHeaders,
        body: urlencoded,
        redirect: 'follow'
        }
        
        let res = await fetch("https://accounts.spotify.com/api/token", requestOptions);
        res = await res.json();
        return res.access_token; 
    }

async search(){
        const access_token = await this.authorize();
        this.setState({access_token});
        const BASE_URL = 'https://api.spotify.com/v1/search';
        let FETCH_URL = `${BASE_URL}?q=${this.state.query}&type=artist&limit=1`; 
        const ALBUM_URL = 'https://api.spotify.com/v1/artists';

        let myHeaders = new Headers();
        myHeaders.append("Authorization", `Bearer ${access_token}`);
        
        const requestOptions = {
            method: 'GET',
            headers: myHeaders
        }

        let res = await fetch(FETCH_URL, requestOptions);
        res = await res.json();
        console.log("ARTIST", res);
}

Upvotes: 2

rags2riches-prog
rags2riches-prog

Reputation: 1761

From the link you have shared, the client credential flow is a client (server-side) that makes a request to the spotify API server. Thus, it is a server-to-server authentication flow (not authorization). You are using the fecth API which is client-side so that means that your implementation should be server-side. If you are using a node.js runtime server-side framework, just look up the http.request API to make a request server-side.

For example, this would be a pure node.js implementation:

 const options = {
   hostname: 'https://accounts.spotify.com/api/token',
   method: 'POST',
   headers: {
     'Content-Type': 'application/x-www-form-urlencoded',
     'Authorization': 'Basic ' + base64(clientID) + ':' + base64(clientSecret)
   }
 };

 const req = http.request(options, (res) => {
   res.setEncoding('utf8');
   // process the data bit by bit or in chunks...
   res.on('data', (chunk) => {});
   // ...and do something with it when there is no more data in response
   res.on('end', () => {
    console.log('No more data in response.');
   });
 });
 
 // handle the error explicitly
 req.on('error', (e) => {
   console.error(`problem with request: ${e.message}`);
 });

 req.end();

Upvotes: 1

Related Questions