Browse Source
Implement User Authorization
Implement User Authorization
Completed step 1 of the Authorization Code Flow documented by the Spotify API.master
Chris
7 years ago
5 changed files with 189 additions and 2 deletions
-
1musicvis/settings.py
-
5requirements.txt
-
132spotifyvis/templates/spotifyvis/index.html
-
3spotifyvis/urls.py
-
50spotifyvis/views.py
@ -1,10 +1,15 @@ |
|||
astroid==1.6.3 |
|||
certifi==2018.4.16 |
|||
chardet==3.0.4 |
|||
Django==2.0.5 |
|||
djangorestframework==3.8.2 |
|||
idna==2.6 |
|||
isort==4.3.4 |
|||
lazy-object-proxy==1.3.1 |
|||
mccabe==0.6.1 |
|||
pylint==1.8.4 |
|||
pytz==2018.4 |
|||
requests==2.18.4 |
|||
six==1.11.0 |
|||
urllib3==1.22 |
|||
wrapt==1.10.11 |
@ -0,0 +1,132 @@ |
|||
<!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="{{images.0.url}}" /> |
|||
</div> |
|||
<div class="media-body"> |
|||
<dl class="dl-horizontal"> |
|||
<dt>Display name</dt><dd class="clearfix">{{display_name}}</dd> |
|||
<dt>Id</dt><dd>{{id}}</dd> |
|||
<dt>Email</dt><dd>{{email}}</dd> |
|||
<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> |
|||
<dt>Profile Image</dt><dd class="clearfix"><a href="{{images.0.url}}">{{images.0.url}}</a></dd> |
|||
<dt>Country</dt><dd>{{country}}</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'); |
|||
var 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, |
|||
error = params.error; |
|||
if (error) { |
|||
alert('There was an error during the authentication'); |
|||
} else { |
|||
if (access_token) { |
|||
// render oauth info |
|||
oauthPlaceholder.innerHTML = oauthTemplate({ |
|||
access_token: access_token, |
|||
refresh_token: refresh_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 { |
|||
// render initial screen |
|||
$('#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> |
|||
</body> |
|||
</html> |
@ -1,6 +1,52 @@ |
|||
from django.shortcuts import render |
|||
from django.shortcuts import render, redirect |
|||
from django.http import HttpResponse |
|||
import math |
|||
import random |
|||
import requests |
|||
import os |
|||
import urllib |
|||
|
|||
def generate_random_string(length): |
|||
"""Generates a random string of a certain length |
|||
|
|||
Args: |
|||
length: the desired length of the randomized string |
|||
|
|||
Returns: |
|||
A random string |
|||
""" |
|||
rand_str = "" |
|||
possible_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |
|||
|
|||
for _ in range(length): |
|||
rand_str += possible_chars[random.randint(0, len(possible_chars) - 1)] |
|||
|
|||
return rand_str |
|||
|
|||
|
|||
# Create your views here. |
|||
def index(request): |
|||
return HttpResponse("You're at the index") |
|||
return render(request, 'spotifyvis/index.html') |
|||
|
|||
|
|||
def login(request): |
|||
|
|||
state_str = generate_random_string(16) |
|||
# use a randomly generated state string to prevent cross-site request forgery attacks |
|||
request.session['state_string'] = state_str |
|||
|
|||
payload = { |
|||
'client_id': os.environ['SPOTIFY_CLIENT_ID'], |
|||
'response_type': 'code', |
|||
'redirect_uri': 'http://localhost:8000/callback', |
|||
'state': state_str, |
|||
'scope': 'user-library-read', |
|||
'show_dialog': False |
|||
} |
|||
|
|||
params = urllib.parse.urlencode(payload) # turn the payload dict into a query string |
|||
authorize_url = "https://accounts.spotify.com/authorize/?{}".format(params) |
|||
return redirect(authorize_url) |
|||
|
|||
def callback(request): |
|||
return HttpResponse("At callback") |
Write
Preview
Loading…
Cancel
Save
Reference in new issue