Skip to content

Instantly share code, notes, and snippets.

@seresk
Created April 5, 2021 20:48
Show Gist options
  • Save seresk/4e1d6c365a422c0904b8a1403a1b01f6 to your computer and use it in GitHub Desktop.
Save seresk/4e1d6c365a422c0904b8a1403a1b01f6 to your computer and use it in GitHub Desktop.
Spotify Authorization server
var express = require('express'); // Express web server framework
var request = require('request'); // "Request" library
var cors = require('cors');
var querystring = require('querystring');
var cookieParser = require('cookie-parser');
var client_id = '*****'; // Your client id
var client_secret = '****'; // Your secret
var redirect_uri = 'http://localhost:8888/callback'; // Your redirect uri
var frontend_redirect_uri = 'http://localhost:4200'; // Your redirect uri
var port = 8888;
var generateRandomString = function (length) {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
var stateKey = 'spotify_auth_state';
var app = express();
app.use(express.static(__dirname + '/public'))
.use(cors())
.use(cookieParser());
app.get('/login', function (req, res) {
var state = generateRandomString(16);
res.cookie(stateKey, state);
// your application requests authorization
var scope = 'user-read-private user-read-email user-library-read playlist-read-private user-top-read user-read-recently-played user-modify-playback-state streaming user-read-playback-state user-follow-read';
res.redirect('https://accounts.spotify.com/authorize?' +
querystring.stringify({
response_type: 'code',
client_id: client_id,
scope: scope,
redirect_uri: redirect_uri,
state: state
}));
});
app.get('/ping', function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
});
app.get('/callback', function (req, res) {
var code = req.query.code || null;
var state = req.query.state || null;
var storedState = req.cookies ? req.cookies[stateKey] : null;
if (state === null || state !== storedState) {
res.redirect('/#' +
querystring.stringify({
error: 'state_mismatch'
}));
} else {
res.clearCookie(stateKey);
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;
var options = {
url: 'https://api.spotify.com/v1/me',
headers: {'Authorization': 'Bearer ' + access_token},
json: true
};
// use the access token to access the Spotify Web API
request.get(options, function (error, response, body) {
// we can also pass the token to the browser to make requests from there
res.redirect(frontend_redirect_uri + '#' +
querystring.stringify({
spotify_access_token: access_token,
spotify_refresh_token: refresh_token,
region: body.country
}));
});
} else {
res.redirect(frontend_redirect_uri + '/#' +
querystring.stringify({
error: 'invalid_token'
}));
}
});
}
});
app.get('/refresh_token', function (req, res) {
// requesting access token from refresh token
var refresh_token = req.query.refresh_token;
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: {'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))},
form: {
grant_type: 'refresh_token',
refresh_token: refresh_token
},
json: true
};
request.post(authOptions, function (error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token;
res.json({
'spotify_access_token': access_token
});
}
});
});
app.listen(port);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment