Skip to content

Instantly share code, notes, and snippets.

@eamonnbell
Created September 5, 2017 15:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eamonnbell/84e3463e964eeae87f59699c7e711f1b to your computer and use it in GitHub Desktop.
Save eamonnbell/84e3463e964eeae87f59699c7e711f1b to your computer and use it in GitHub Desktop.
Example of Implicit Grant flow authorization with Spotify API.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Spotify API - Implicit Grant Flow</title>
</head>
<body>
<p>Example of Implicit Grant flow authorization with Spotify API. Uses native browser APIs only.
<p>
<form action="" id="main_form">
<label for="client_id">client_id:</label><input name="client_id" type="text" value=>
<hr>
<label for="response_type">response_type:</label><input name="response_type" type="text" value="token" readonly>
<hr>
<label for="redirect_uri">redirect_uri:</label><input name="redirect_uri" type="text" value="http://localhost:8080/">
<hr>
<label for="scope">scope:</label><input name="scope" type="text" value="">
</form>
<hr>
<button id="build_link">Build auth link</button>
<hr> Auth link: <a id="auth_link" href=""></a>
<hr> Everything below here depends on having the bearer token issued by Spotify. Have a look in the navigation bar
and see if it the access_token parameter been appended to the URI as part of a fragment.
<hr>
<button id="fetch_profile_info">Fetch profile information</button>
<hr>
<div id="profile_info">
</div>
</body>
<script>
function getFormData(formId) {
const form = document.getElementById(formId);
const formData = new FormData(form);
return formData;
};
const AUTH_BASE_URL = 'https://accounts.spotify.com/authorize';
const API_ENDPOINT = 'https://api.spotify.com/v1/me';
let ACCESS_TOKEN;
function formDataToParams(formData) {
const params = new URLSearchParams('');
for (let [key, value] of formData.entries()) {
params.set(key, value)
}
return params;
}
function getCurrentQueryParameters(delimiter = '#') {
// the access_token is passed back in a URL fragment, not a query string
// errors, on the other hand are passed back in a query string
const currentLocation = String(window.location).split(delimiter)[1];
const params = new URLSearchParams(currentLocation);
return params;
}
function buildAuthLink() {
const params = formDataToParams(getFormData('main_form'));
const authURI = AUTH_BASE_URL + '?' + params;
const authLinkAnchor = document.querySelector('a#auth_link');
authLinkAnchor.setAttribute('href', authURI);
authLinkAnchor.textContent = authURI;
}
function updateProfileInformation(json) {
const infoString = `username: ${json.id} has ${json.followers.total} follower(s) on Spotify`;
const profileInfoElement = document.querySelector('#profile_info');
profileInfoElement.textContent = infoString;
}
function fetchProfileInformation() {
const currentQueryParameters = getCurrentQueryParameters('#');
ACCESS_TOKEN = currentQueryParameters.get('access_token');
const fetchOptions = {
method: 'GET',
headers: new Headers({
'Authorization': `Bearer ${ACCESS_TOKEN}`
})
};
fetch(API_ENDPOINT, fetchOptions).then(function (response) {
return response.json();
}).then(function (json) {
console.log(json);
updateProfileInformation(json);
}).catch(function (error) {
console.log(error);
});
}
const buildButton = document.querySelector('button#build_link');
buildButton.addEventListener('click', buildAuthLink);
const fetchButton = document.querySelector('button#fetch_profile_info');
fetchButton.addEventListener('click', fetchProfileInformation);
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment