if you’re implementing authorization in a mobile app, single page web app, or any other type of application where the client secret can’t be safely stored.
Authorization Code with PKCE Flow
in here
I will demo a more simple version Authorization Code Flow
but the concept is the same.
Authorization Code Flow in here

Demo code save as demo.js
const axios = require('axios')
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
// for raw JSON of Body
app.use(express.json());
const REDIRECT_URI='http://localhost:3000' // mine is http://localhost:3000/callback
const CLIENT_ID='<your client ID>'
const CLIENT_SECRET='<your client secret>'
const SCOPE=['playlist-read-private']
const PORT = 3000
const PLATLIST_ID='<your playlist ID>'
// User login URL
app.get("/user", (request, response) => {
const redirect_url = `https://accounts.spotify.com/authorize?response_type=code&client_id=${CLIENT_ID}&scope=${SCOPE}&state=123456&redirect_uri=${REDIRECT_URI}&prompt=consent`
response.redirect(redirect_url)
})
// callback URL
app.get("/", async (request, response) => {
const code = request.query["code"]
await axios.post(
url = 'https://accounts.spotify.com/api/token',
data = new URLSearchParams({
'grant_type': 'authorization_code',
'redirect_uri': REDIRECT_URI,
'code': code
}),
config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
params: {
'grant_type': 'client_credentials'
},
auth: {
username: CLIENT_ID,
password: CLIENT_SECRET
}
})
.then(resp1 => {
axios.get(
url = `https://api.spotify.com/v1/playlists/${PLATLIST_ID}`,
config = {
headers: {
'Accept-Encoding': 'application/json',
Authorization: `Bearer ${resp1.data.access_token}`
}
}
).then(resp2 => {
return response.send(JSON.stringify(resp2.data));
})
});
})
// use your <your redirect URL>'s port
app.listen(PORT, () => { console.log(`Listening on : http://localhost:${PORT}`) })
Install dependencies
npm install axios express cors
Run the server
node demo.js
Login to get a token by Browser
http://localhost:3000/user
Login Dialog will show

Result from express server

Scopes
Each API need to match scope,
Example,
https://developer.spotify.com/documentation/web-api/concepts/scopes