first commit
This commit is contained in:
commit
684ad7dae1
9 changed files with 478 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
node_modules/
|
36
README.md
Normal file
36
README.md
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Spotify Accounts Authentication Examples
|
||||||
|
|
||||||
|
This project contains basic demos showing the different oAuth2 flows for [authenticating against the Spotify Web API](https://developer.spotify.com/spotify-web-api/authorization-guide/).
|
||||||
|
|
||||||
|
These examples cover:
|
||||||
|
|
||||||
|
* Authorization Code flow
|
||||||
|
* Client Credentials flow
|
||||||
|
* Implicit Grant flow
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
These examples run on Node.js. On [its website](http://www.nodejs.org/download/) you can find instructions on how to install it. You can also follow [this gist](https://gist.github.com/isaacs/579814) for a quick and easy way to install Node.js and npm.
|
||||||
|
|
||||||
|
Once installed, clone the repository and install its dependencies running:
|
||||||
|
|
||||||
|
$ npm install
|
||||||
|
|
||||||
|
## Running the examples
|
||||||
|
In order to run the different examples, open the folder with the name of the flow you want to try out, and run its `app.js` file. For instance, to run the Authorization Code example do:
|
||||||
|
|
||||||
|
$ cd authorization_code
|
||||||
|
$ node app.js
|
||||||
|
|
||||||
|
Then, open `http://localhost:8888` in a browser.
|
||||||
|
|
||||||
|
### Using your own credentials
|
||||||
|
The examples contains a working client ID and secret key. Note, however, that they might be rate limited if they are used frequently. If you are planning to create an application, we recommend you register your app and get your own credentials instead of using the ones in this project.
|
||||||
|
|
||||||
|
Go to [My Applications on Spotify Developer](https://developer.spotify.com/my-applications) and create your application. For the examples, we registered these Redirect URIs:
|
||||||
|
|
||||||
|
* http://localhost:8888 (needed for the implicit grant flow)
|
||||||
|
* http://localhost:8888/callback
|
||||||
|
|
||||||
|
Once you have created your app, replace the `client_id`, `redirect_uri` and `secret_key` in the examples with the ones you get from My Applications.
|
||||||
|
|
6
app.js
Normal file
6
app.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
var http = require("http");
|
||||||
|
http.createServer(function(request, response) {
|
||||||
|
response.writeHead(200, {"Content-Type": "text/plain"});
|
||||||
|
response.write("Hello World");
|
||||||
|
response.end();
|
||||||
|
}).listen(8888);
|
102
authorization_code/app.js
Normal file
102
authorization_code/app.js
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/**
|
||||||
|
* This is an example of a basic node.js script that performs
|
||||||
|
* the Authorization Code oAuth2 flow to authenticate against
|
||||||
|
* the Spotify Accounts.
|
||||||
|
*
|
||||||
|
* For more information, read
|
||||||
|
* https://developer.spotify.com/spotify-web-api/authorization-guide/#authorization_code_flow
|
||||||
|
*/
|
||||||
|
|
||||||
|
var express = require('express'); // Express web server framework
|
||||||
|
var request = require('request'); // "Request" library
|
||||||
|
var querystring = require('querystring');
|
||||||
|
|
||||||
|
var client_id = '03ffe0cac0a0401aa6673c3cf6d02ced'; // Your client id
|
||||||
|
var secret_key = 'a57c43efb9644574a96d6623fb8bfbc2'; // Your secret key
|
||||||
|
var redirect_uri = 'http://localhost:8888/callback'; // Your redirect uri
|
||||||
|
|
||||||
|
var app = express();
|
||||||
|
|
||||||
|
app.use(express.static(__dirname + '/public'));
|
||||||
|
|
||||||
|
app.get('/login', function(req, res) {
|
||||||
|
|
||||||
|
// your application requests authorization
|
||||||
|
var scope = 'user-read-private user-read-email';
|
||||||
|
res.redirect('https://accounts.spotify.com/authorize?' +
|
||||||
|
querystring.stringify({
|
||||||
|
response_type: 'code',
|
||||||
|
client_id: client_id,
|
||||||
|
scope: scope,
|
||||||
|
redirect_uri: redirect_uri
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/callback', function(req, res) {
|
||||||
|
|
||||||
|
// your application requests refresh and access tokens
|
||||||
|
var code = req.query.code;
|
||||||
|
var authOptions = {
|
||||||
|
url: 'https://accounts.spotify.com/api/token',
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + secret_key).toString('base64'))
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
code: code,
|
||||||
|
redirect_uri: redirect_uri,
|
||||||
|
grant_type: 'authorization_code'
|
||||||
|
},
|
||||||
|
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) {
|
||||||
|
console.log(body);
|
||||||
|
});
|
||||||
|
|
||||||
|
// we can also pass the token to the browser to make requests from there
|
||||||
|
res.redirect('/#' +
|
||||||
|
querystring.stringify({
|
||||||
|
access_token: access_token,
|
||||||
|
refresh_token: refresh_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 + ':' + secret_key).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.send({
|
||||||
|
'access_token': access_token
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(8888);
|
134
authorization_code/public/index.html
Normal file
134
authorization_code/public/index.html
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Example of the Authorization Code 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 Authorization Code flow</h1>
|
||||||
|
<a href="/login" class="btn btn-primary">Log in with Spotify</a>
|
||||||
|
</div>
|
||||||
|
<div id="loggedin">
|
||||||
|
<div id="user-profile">
|
||||||
|
</div>
|
||||||
|
<div id="oauth">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-default" id="obtain-new-token">Obtain new token using the refresh token</button>
|
||||||
|
</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">
|
||||||
|
<img class="media-object" width="150" src="{{image.url}}" />
|
||||||
|
</div>
|
||||||
|
<div class="media-body">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>Display name</dt><dd>{{display_name}}</dd>
|
||||||
|
<dt>Id</dt><dd>{{id}}</dd>
|
||||||
|
<dt>Email</dt><dd>{{email}}</dd>
|
||||||
|
<dt>Spotify URI</dt><dd><a href="{{self.uri}}">{{self.uri}}</a></dd>
|
||||||
|
<dt>Link</dt><dd><a href="{{self.web}}">{{self.web}}</a></dd>
|
||||||
|
<dt>Profile Image</dt><dd><a href="{{image.url}}">{{image.url}}</a></dd>
|
||||||
|
</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>
|
||||||
|
<dt>Refresh token</dt><dd class="text-overflow">{{refresh_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() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
var access_token = params.access_token
|
||||||
|
refresh_token = params.refresh_token;
|
||||||
|
|
||||||
|
oauthPlaceholder.innerHTML = oauthTemplate({
|
||||||
|
access_token: access_token,
|
||||||
|
refresh_token: refresh_token
|
||||||
|
});
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('obtain-new-token').addEventListener('click', function() {
|
||||||
|
$.ajax({
|
||||||
|
url: '/refresh_token',
|
||||||
|
data: {
|
||||||
|
'refresh_token': refresh_token
|
||||||
|
}
|
||||||
|
}).done(function(data) {
|
||||||
|
access_token = data.access_token;
|
||||||
|
oauthPlaceholder.innerHTML = oauthTemplate({
|
||||||
|
access_token: access_token,
|
||||||
|
refresh_token: refresh_token
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
|
|
44
client_credentials/app.js
Normal file
44
client_credentials/app.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* This is an example of a basic node.js script that performs
|
||||||
|
* the Client Credentials oAuth2 flow to authenticate against
|
||||||
|
* the Spotify Accounts.
|
||||||
|
*
|
||||||
|
* For more information, read
|
||||||
|
* https://developer.spotify.com/spotify-web-api/authorization-guide/#client_credentials_flow
|
||||||
|
*/
|
||||||
|
|
||||||
|
var request = require('request'); // "Request" library
|
||||||
|
|
||||||
|
var client_id = '03ffe0cac0a0401aa6673c3cf6d02ced'; // Your client id
|
||||||
|
var secret_key = 'a57c43efb9644574a96d6623fb8bfbc2'; // Your secret key
|
||||||
|
var redirect_uri = 'http://localhost:8888/callback'; // Your redirect uri
|
||||||
|
|
||||||
|
// your application requests authorization
|
||||||
|
var authOptions = {
|
||||||
|
url: 'https://accounts.spotify.com/api/token',
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + secret_key).toString('base64'))
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
grant_type: 'client_credentials'
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
};
|
||||||
|
|
||||||
|
request.post(authOptions, function(error, response, body) {
|
||||||
|
if (!error && response.statusCode === 200) {
|
||||||
|
|
||||||
|
// use the access token to access the Spotify Web API
|
||||||
|
var token = body.access_token;
|
||||||
|
var options = {
|
||||||
|
url: 'https://api.spotify.com/v1/users/jmperezperez',
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer ' + token
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
};
|
||||||
|
request.get(options, function(error, response, body) {
|
||||||
|
console.log(body);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
13
implicit_grant/app.js
Normal file
13
implicit_grant/app.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* This is an example of a basic node.js script that performs
|
||||||
|
* the Implicit Grant oAuth2 flow to authenticate against
|
||||||
|
* the Spotify Accounts.
|
||||||
|
*
|
||||||
|
* For more information, read
|
||||||
|
* https://developer.spotify.com/spotify-web-api/authorization-guide/#implicit_grant_flow
|
||||||
|
*/
|
||||||
|
|
||||||
|
var express = require('express'); // Express web server framework
|
||||||
|
var app = express();
|
||||||
|
app.use(express.static(__dirname + '/public'));
|
||||||
|
app.listen(8888);
|
130
implicit_grant/public/index.html
Normal file
130
implicit_grant/public/index.html
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
<!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">
|
||||||
|
<img class="media-object" width="150" src="{{image.url}}" />
|
||||||
|
</div>
|
||||||
|
<div class="media-body">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>Display name</dt><dd>{{display_name}}</dd>
|
||||||
|
<dt>Id</dt><dd>{{id}}</dd>
|
||||||
|
<dt>Email</dt><dd>{{email}}</dd>
|
||||||
|
<dt>Spotify URI</dt><dd><a href="{{self.uri}}">{{self.uri}}</a></dd>
|
||||||
|
<dt>Link</dt><dd><a href="{{self.web}}">{{self.web}}</a></dd>
|
||||||
|
<dt>Profile Image</dt><dd><a href="{{image.url}}">{{image.url}}</a></dd>
|
||||||
|
</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() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
var access_token = params.access_token;
|
||||||
|
|
||||||
|
oauthPlaceholder.innerHTML = oauthTemplate({
|
||||||
|
access_token: access_token
|
||||||
|
});
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('login-button').addEventListener('click', function() {
|
||||||
|
|
||||||
|
var client_id = '03ffe0cac0a0401aa6673c3cf6d02ced'; // Your client id
|
||||||
|
var redirect_uri = 'http://localhost:8888/'; // Your redirect uri
|
||||||
|
|
||||||
|
var scope = 'user-read-private user-read-email';
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
window.location = url;
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</html>
|
12
package.json
Normal file
12
package.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"author": "Doozer",
|
||||||
|
"name": "web-api-code-example",
|
||||||
|
"description": "Basic examples of the Spotify authorization flows through oAuth2",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"main": "app.js",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "~4.0.0",
|
||||||
|
"request": "~2.34.0",
|
||||||
|
"querystring": "~0.2.0"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue