2014-05-14 10:27:27 +02:00
|
|
|
<!doctype html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<title>Example of the Implicit Grant flow with Spotify</title>
|
|
|
|
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
|
|
|
|
<style type="text/css">
|
|
|
|
#login, #loggedin {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
.text-overflow {
|
|
|
|
overflow: hidden;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
white-space: nowrap;
|
|
|
|
width: 500px;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body>
|
|
|
|
<div class="container">
|
|
|
|
<div id="login">
|
|
|
|
<h1>This is an example of the Implicit Grant flow</h1>
|
|
|
|
<button id="login-button" class="btn btn-primary">Log in with Spotify</button>
|
|
|
|
</div>
|
|
|
|
<div id="loggedin">
|
|
|
|
<div id="user-profile">
|
|
|
|
</div>
|
|
|
|
<div id="oauth">
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<script id="user-profile-template" type="text/x-handlebars-template">
|
|
|
|
<h1>Logged in as {{display_name}}</h1>
|
|
|
|
<div class="media">
|
|
|
|
<div class="pull-left">
|
2014-06-03 13:26:18 +02:00
|
|
|
<img class="media-object" width="150" src="{{images.0.url}}" />
|
2014-05-14 10:27:27 +02:00
|
|
|
</div>
|
|
|
|
<div class="media-body">
|
|
|
|
<dl class="dl-horizontal">
|
2014-06-05 00:14:48 +02:00
|
|
|
<dt>Display name</dt><dd class="clearfix">{{display_name}}</dd>
|
2014-05-14 10:27:27 +02:00
|
|
|
<dt>Id</dt><dd>{{id}}</dd>
|
|
|
|
<dt>Email</dt><dd>{{email}}</dd>
|
2014-06-03 13:26:18 +02:00
|
|
|
<dt>Spotify URI</dt><dd><a href="{{external_urls.spotify}}">{{external_urls.spotify}}</a></dd>
|
|
|
|
<dt>Link</dt><dd><a href="{{href}}">{{href}}</a></dd>
|
2014-06-05 00:14:48 +02:00
|
|
|
<dt>Profile Image</dt><dd class="clearfix"><a href="{{images.0.url}}">{{images.0.url}}</a></dd>
|
|
|
|
<dt>Country</dt><dd>{{country}}</dd>
|
2014-05-14 10:27:27 +02:00
|
|
|
</dl>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<script id="oauth-template" type="text/x-handlebars-template">
|
|
|
|
<h2>oAuth info</h2>
|
|
|
|
<dl class="dl-horizontal">
|
|
|
|
<dt>Access token</dt><dd class="text-overflow">{{access_token}}</dd>
|
|
|
|
</dl>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0-alpha.1/handlebars.min.js"></script>
|
|
|
|
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
|
|
|
|
<script>
|
|
|
|
(function() {
|
|
|
|
|
2014-06-30 10:11:04 +02:00
|
|
|
var stateKey = 'spotify_auth_state';
|
|
|
|
|
2014-05-14 10:27:27 +02:00
|
|
|
/**
|
|
|
|
* Obtains parameters from the hash of the URL
|
|
|
|
* @return Object
|
|
|
|
*/
|
|
|
|
function getHashParams() {
|
|
|
|
var hashParams = {};
|
|
|
|
var e, r = /([^&;=]+)=?([^&;]*)/g,
|
|
|
|
q = window.location.hash.substring(1);
|
|
|
|
while ( e = r.exec(q)) {
|
|
|
|
hashParams[e[1]] = decodeURIComponent(e[2]);
|
|
|
|
}
|
|
|
|
return hashParams;
|
|
|
|
}
|
|
|
|
|
2014-06-30 10:11:04 +02:00
|
|
|
/**
|
|
|
|
* Generates a random string containing numbers and letters
|
|
|
|
* @param {number} length The length of the string
|
|
|
|
* @return {string} The generated string
|
|
|
|
*/
|
|
|
|
function generateRandomString(length) {
|
|
|
|
var text = '';
|
|
|
|
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
|
|
|
|
|
|
for (var i = 0; i < length; i++) {
|
|
|
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
|
|
}
|
|
|
|
return text;
|
|
|
|
};
|
|
|
|
|
2014-05-14 10:27:27 +02:00
|
|
|
var userProfileSource = document.getElementById('user-profile-template').innerHTML,
|
|
|
|
userProfileTemplate = Handlebars.compile(userProfileSource),
|
|
|
|
userProfilePlaceholder = document.getElementById('user-profile');
|
|
|
|
|
|
|
|
oauthSource = document.getElementById('oauth-template').innerHTML,
|
|
|
|
oauthTemplate = Handlebars.compile(oauthSource),
|
|
|
|
oauthPlaceholder = document.getElementById('oauth');
|
|
|
|
|
|
|
|
var params = getHashParams();
|
|
|
|
|
2014-06-30 10:11:04 +02:00
|
|
|
var access_token = params.access_token,
|
|
|
|
state = params.state,
|
|
|
|
storedState = localStorage.getItem(stateKey);
|
|
|
|
|
|
|
|
if (access_token && (state == null || state !== storedState)) {
|
|
|
|
alert('There was an error during the authentication');
|
2014-05-14 10:27:27 +02:00
|
|
|
} else {
|
2014-06-30 10:11:04 +02:00
|
|
|
localStorage.removeItem(stateKey);
|
|
|
|
if (access_token) {
|
|
|
|
$.ajax({
|
|
|
|
url: 'https://api.spotify.com/v1/me',
|
|
|
|
headers: {
|
|
|
|
'Authorization': 'Bearer ' + access_token
|
|
|
|
},
|
|
|
|
success: function(response) {
|
|
|
|
userProfilePlaceholder.innerHTML = userProfileTemplate(response);
|
|
|
|
|
|
|
|
$('#login').hide();
|
|
|
|
$('#loggedin').show();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
$('#login').show();
|
|
|
|
$('#loggedin').hide();
|
|
|
|
}
|
2014-05-14 10:27:27 +02:00
|
|
|
|
2014-06-30 10:11:04 +02:00
|
|
|
document.getElementById('login-button').addEventListener('click', function() {
|
2014-05-14 10:27:27 +02:00
|
|
|
|
2014-06-30 10:11:04 +02:00
|
|
|
var client_id = '03ffe0cac0a0401aa6673c3cf6d02ced'; // Your client id
|
|
|
|
var redirect_uri = 'http://localhost:8888/'; // Your redirect uri
|
2014-05-14 10:27:27 +02:00
|
|
|
|
2014-06-30 10:11:04 +02:00
|
|
|
var state = generateRandomString(16);
|
2014-05-14 10:27:27 +02:00
|
|
|
|
2014-06-30 10:11:04 +02:00
|
|
|
localStorage.setItem(stateKey, state);
|
|
|
|
var scope = 'user-read-private user-read-email';
|
2014-05-14 10:27:27 +02:00
|
|
|
|
2014-06-30 10:11:04 +02:00
|
|
|
var url = 'https://accounts.spotify.com/authorize';
|
|
|
|
url += '?response_type=token';
|
|
|
|
url += '&client_id=' + encodeURIComponent(client_id);
|
|
|
|
url += '&scope=' + encodeURIComponent(scope);
|
|
|
|
url += '&redirect_uri=' + encodeURIComponent(redirect_uri);
|
|
|
|
url += '&state=' + encodeURIComponent(state);
|
2014-05-14 10:27:27 +02:00
|
|
|
|
2014-06-30 10:11:04 +02:00
|
|
|
window.location = url;
|
|
|
|
}, false);
|
|
|
|
}
|
2014-05-14 10:27:27 +02:00
|
|
|
})();
|
|
|
|
</script>
|
|
|
|
</html>
|