Type in your question below and we'll check to see what answers we can find...
Loading article...
Submitting...
If you couldn't find any answers in the previous step then we need to post your question in the community and wait for someone to respond. You'll be notified when that happens.
Simply add some detail to your question and refine the title if needed, choose the relevant category, then post.
Before we can post your question we need you to quickly make an account (or sign in if you already have one).
Don't worry - it's quick and painless! Just click below, and once you're logged in we'll bring you right back here and post your question. We'll remember what you've already typed in so you won't have to do it again.
Plan
Premium
Country
Canada
Device
Chrome. Macbook Pro 2013
Operating System
Mac OS X Catalina
My Question or Issue
I am trying to set up my web application to use the Proof Key for Code Exchange. However, when I try try to get the access_token by doing a POST request to https://accounts.spotify.com/api/token, I get the following error
error: "invalid_request"
error_description: "Invalid client secret"
This message does not make sense to me since the PKCE method does not require a client secret. This is what my javascript code looks like. The code is the authorization_code from the redirect callback and the codeVerifier is used for generating the challenge as described in the docs.
const fetchUrl = "https://accounts.spotify.com/api/token";
const fetchBody = {
client_id: process.env.SPOTIFY_CLIENT_ID,
grant_type: "authorization_code",
code: code,
redirect_uri: process.env.BASE_URL + "/spotify-callback",
code_verifier: codeVerifier,
};
const searchParams = Object.keys(fetchBody)
.map((key) => {
return encodeURIComponent(key) + "=" + encodeURIComponent(fetchBody[key]);
})
.join("&");
const response = await fetch(fetchUrl, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: searchParams,
});
Please could I get some advice on what I'm doing wrong? I have read and reread the documentation several times but I cannot figure it out.
More info
For calculating the sha256: https://www.npmjs.com/package/js-sha256
For performing base64Url encoding: https://www.npmjs.com/package/base64url
For random string for code verifier: https://www.npmjs.com/package/crypto-random-string
I just got a proof-of-concept for PKCE running on my local machine. I'm using Axios, but the code's almost identical to yours. I don't think you want the parameters sent in "body". (Yes, I know that the documentation makes it seem that you must do this.)
My Axios call is like this:
const postConfig = {
headers: {
'content-type': 'application/x-www-form-urlencoded',
},
};
return await instance.post(path, qs.stringify(parameters), postConfig)
.catch(() => ({offline: true}));
Notice that the parameters are sent in the path.
My code that calls this looks like this:
const parameters = {
client_id: use.global.clientId,
grant_type: 'authorization_code',
code: local.getItem('code'),
redirect_uri: getRedirectUri() + location.pathname,
code_verifier: local.getItem('codeVerifier'),
};
return api.call('POST', 'https://accounts.spotify.com/api/token', parameters)
.then(response => {
const {access_token, expires_in, refresh_token} = response.data;
if (access_token)
setAccessToken(access_token);
if (expires_in)
setAccessTokenExpiresOn((Math.floor(Date.now() / 1000)) + expires_in);
if (refresh_token)
setRefreshToken(refresh_token);
});
Make sure that in your initial redirect request(step 2.), the code_challenge and code_challenge_method are specified correctly, otherwise the endpoint will assume you are trying to do the "regular" Authorization work flow. This is why it is expecting a client_secret.
In order to try out the PKCE authorization flow I created a little example repository.
Don't hesitate to try it out and compare with your project:
Hey there you, Yeah, you! 😁 Welcome - we're glad you joined the Spotify Community! While you here, let's have a fun game and get…