Django & React Tutorial #13 - Spotify API Tutorial (Authentication & Tokens)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello everybody and welcome to another django and react tutorial video in part 13 of this series what we're going to be doing is actually working with the spotify api now i want to give a warning before we dive into anything this is fairly complicated in fact this is pretty advanced this took me a really long time to figure out before filming this video and i just want to make sure that i'm not giving you the impression that this is easy or that i came up with this you know within the duration of the video this was pre-coded this took me a long time to figure out if you ever want to use these kind of apis typically you have to do a lot of reading and a lot of research on their websites a lot of trial and error and just kind of messing around and trying to figure things out which is exactly what i did before this video so i will leave links to most of the resources that i use to discover this or figure this out in the description in case you're interested but of course i'm going to try my best to explain how everything works so anyways let me talk about what we actually need to do here and what kind of the goal of this video is so we want to be able to control a user's music we want to be able to pause it fast forward the song rewind the song whatever we want control over their music now this requires two things from spotify first we need to register an application with spotify so our actual website we can refer to that as an application we need to register that with spotify and tell them hey this is our app we're using user data whatever we just need to tell them that we have some application that's using their api then what we need to do is every single user that's using our website and whose music we're going to control we need to give them to grant us permission to use and access their spotify information so they need to give our application explicit permission so the basic kind of flow of things here is going to be we authenticate our application with spotify then the user authenticates our application so it says hey your application has access to my information it can control the music so on and so forth and then using that authentication or using what we're going to call tokens and i'll talk about what those are in a second we'll actually be able to send requests to the spotify api that will in turn control the user's music so that's kind of the flow and this diagram in front of me somewhat describes what's actually going to happen i'm going to try to kind of break this down and walk through it but i just want to talk to you about what we're doing because if i don't it's just going to seem really confusing if we go through all the steps without kind of tying them all together and seeing the big picture so we have our application on the left spotify account services or service which we're just going to call the spotify api then we have our user so we're going to start by creating some application with spotify that will be denoted by application our application is going to have a client id it's also going to have a client secret it's pretty much the identifier for our application so we start at the very first step by requesting authorization to access data so we do that with spotify we're pretty much saying hey spotify can our application access spotify information it's going to tell us yes or it's going to tell us no depending on if the information we send it is correct we need to send it this information so the client id the response type the redirect uri the state and the scope now what's going to happen here is this is going to display a scope and prompt to the user to log in now let's let me just break this down because uh this is not too descriptive so a scope is pretty much what you have access to what information you want to have access to so do you want the user's email do you want their library do you want their playlist whatever that's what you're putting in the scope and well based on what scope you send to spotify spotify will show a different prompt to the user to allow your application access to that information so imagine you go on some website and you log in with facebook and then all of a sudden it says you know facebook wants to access or sorry this third party application wants to access this information do you give it permission and then this is like a facebook website that's popping up right you press yes i grant permission then it redirects back to the other application so that's where the redirect uri comes in after this prompt appears on the screen the user will log in to their spotify account and then they will press yes i authorize this application which is our application to have access to this specific information then it will redirect us with the redirect uri back to our own website so at that point in time we go back to our application and now the user's given us authorization to use their information so what's actually going to happen is we're going to be sent a code and we use this code to actually request what's known as a token now this token is what we're going to use whenever we send a request to spotify to say hey we have access to this user's information because we have this special token and if that special token matches what spotify is stored on their end then it will allow us to actually get information so we're just requesting some kind of token now i don't know why they make it this confusing but essentially it sends us some code we use that code to request a token then we use that token to actually send requests so we say say here request access and refresh tokens so we send our client id we send our client secret and we send this code that was sent to us from the user authorizing our application then what's going to happen is this returns to us the access and refresh tokens now what these tokens are are the following the access token is what we use to access information the refresh token is what we use to uh i guess ask for another token so our access token expires after one hour so after every hour we need to refresh this token so we have to send not the access token now but the refresh token to spotify and then it says okay yep that was a valid refresh token and it sends us back a new access token that is valid so that's the idea there and then it tells us when this access token expires but from my experience it always expires after one hour anyways once we now have access to a re uh uh sorry access and refresh token we are able to send requests to the spotify api and control the user's music so that's kind of the flow i know this is confusing we'll go through it step by step but i just wanted to break it down before we start to make sure everyone's on the same page and they know what we're about to do in this probably hour or so long tutorial so we're going to dive in we're going to start coding but first a quick word from our sponsor algo expert so algo expert is the best platform to use to prepare for your software engineering coding interviews as you guys know i work at algo expert and i'm continually adding new questions to the platform if you guys are looking to ace your coding interviews check out algo expert from the link in the description and use the discount code tech with tim for a discount on the platform all right so let's continue i'm going to get out of this now i'm actually going to go to this website which is the developer.spotify.com so kind of like the developer website for spotify now i'll leave a link to this in the description but go to this site and before you go here you actually need to create a spotify account so it doesn't matter if this is a premium account or a free account or whatever it doesn't matter all of this will work once you come to this website and you have the account log into that account it's going to bring into something that looks like this now you guys probably aren't going to see any applications here these are my different spotify applications and what we're going to do is create an app now this app is going to represent our website so this is the application that i was just talking about in uh in this diagram right here so this blue application is this app that we're making right now so call this whatever you want i'm just going to call this tutorial one just because i already have one named tutorial then i think a description is required so i'll just do tutorial one all right i'll check the boxes press create okay so now it's going to show us a client id and a client secret now if we go back to this diagram here the first thing we send is the client id so we need to keep track of both the client id and the client secret but we don't want this information to be public like we don't want to store this on the front end we don't want anyone to see this other than our application specifically this client secret we don't want anyone to see what this is so keep that in mind i'm showing you mine just for the purpose of this tutorial but don't share this with anyone else okay so now that we have this page open let's leave it open because we're going to need to work on this a few times but now we're going to go to the code and then start working on something else so the first thing that i actually want to do is i want to create a new application inside of my django project that's going to handle all of the stuff specific to spotify so we're going to make a new app we're going to say python manage.pi and then start app like that and then we'll call this spotify for simplicity all right so let's make a new spotify app you can see one's going to show up right here now the first thing we'll do inside of this application is we'll just create a few files that we need so we'll make our urls.pi file uh urls.pi like that we'll also make another file inside of here and we're going to call this credentials or yeah we'll call it credentials that's fine so credentials.pie now inside of credentials.pi this is where this is where we are going to store our spotify credentials so our client id our client secret and also the redirect uri or the redirect url whatever you want to call it so the first thing i'm going to do inside of here is to find some variables i'm going to say client id is equal to i'm going to put a string i'm going to go to the website where the client id is i'm going to copy it i'm going to paste it in there alright so client id then i'm going to say in all capitals again client underscore secret like that is equal to a string then i'm going to go take my client secret so let's grab it right here copy it and paste it in lastly i'm going to make my redirect underscore uri and this is just going to be equal to an empty string for right now we will change this later now i just want to note here that although i'm storing this information in a file typically the preferred way to do this is through environment variables if you knew if you know how to use environment variables feel free to use them but i'm not going to use them for this tutorial just because it adds a layer of complexity that we really don't need for this this purpose anyways let's continue i'm going to close the credentials.pi file i can close the urls.pi file and now what i want to do is start setting up this authentication flow so i need some endpoints or i need some functions or something that can send requests to spotify to authenticate our application as well as to authenticate a user so i'm going to go inside of my views.pi file inside of the spotify application that we just created i'm going to start by creating the first view which is going to be the view that can authenticate our application or request access right so if we go back and look at that diagram we're going to be referring to this quite a bit the first thing here this is what we need to do request authorization to access data using the client id the redirect uri and the scope and all of that so what i'm going to do is remove this comment i'm going to import a few things i'm going to say from dot credentials so that file we just wrote import and i'm going to import everything so redirect uri i want the client secret and i also want the client id like that next i'm going to say from uh i guess this is rest underscore framework import and sorry this is restframework.views import api view then i'm going to make a class i'm going to say class auth url and this will inherit from api view and then i'm going to define a get method this is going to take self and request and an optional format so format equals none and inside of here we're going to start writing out the request that we need to send to the spotify api so actually let's import one more thing up here i'm going to say from the request module in python which i think is by default installed maybe it's not anyways just do yourself a favor because i don't know if request is a default module in python and you can install it with pip so pip install requests i assume if you've made it this far you know how to use pip um but yeah install the request module although i think it by default comes installed anyways from requests we're going to import request with a capital r then we're going to import post this is just going to make it easier for us to actually send a request now the first thing i'm going to do is inside of this get function i'm going to say scopes equals and i'm going to start writing out a long scope in fact actually let me just copy and paste it in because it's not really worth me writing it out you guys can pause and copy it but again what the scope is is what information we want to access so we want the user read playback state the user modify playback state and the user read currently playing these are the things that we want because this is what we actually want to be able to do with our application now if you wanted to do more you would have to add all those other specific scopes now if you're wondering where you find these scopes this is from the spotify developer website so from the documentation i actually can't remember exactly where i found all these scopes but you would just have to look up look for those on the spotify website anyways these are the scopes that we need for this application so i'm going to say scopes like that next i'm going to say url is equal to request this should be a uppercase actually as the first one so we'll say request and then the type of request is going to be a get request and we're going to send this to https colon slash and this is going to be accounts.spotify.com authorize like that this is the first url that we need to hit and this is the specific one that we hit when we're requesting authorization so let's do that then we're going to say params is equal to again this stands for parameters and we're going to pass in all of the required information so if we go back here we need the client id response type direct redirect uri and state and scope now we actually don't need state that is a what do you call it optional parameter to pass in here and i'm not really going to talk about exactly what it does but we can just omit it for now so we're going to say scope is equal to scopes i guess we could have put this as scope as well it doesn't matter we're going to say response hyphen or not hyphen underscore type and we want this to be equal to the string code the reason for this is we are requesting that we get sent a code back that will allow us to authenticate a user so we're taking the code next we're going to say redirect underscore and then uri like that and this is going to be equal to the redirect uri variable that we imported up above so redirect uri and if we want to change the redirect redirect uri we'll go to the credentials file to do that next we are going to say that the client underscore id is equal to the client id like that remove the comma and then here we'll say dot prepare and then dot url now what this is going to do is just generate a url for us the output of this will be a string and the reason why i'm not actually sending the request right now is because what i want to do is i want to have the front end get this request so i want the front end to get this url here and then send it from there you'll see why but essentially what this view right here is going to do or what this api endpoint is going to do for us is just return a url that we can go to to authenticate our spotify application so we're preparing the url we have our scopes and then finally we're going to return from here a response and we're going to say url uh sorry this should be inside of curly braces like that i'm going to say url colon url and then status is equal to status and we need to import status so i think this is from where do i get status uh from rest framework we already have that okay so from rest framework like that import status okay now we're going to say status dot http underscore 200 underscore okay all right and we also need to import response my bad so we're going to say import status and import response i think that's the right import but let me just make sure nope of course that's the wrong import we're going to say from nope come on what's going on here with my code from rest framework dot and i guess this is response import response and this should be a lowercase okay so from rest framework dot response import response nice so now what we're doing is we've just set up an api endpoint that will return to us a url and this url we will use uh to authenticate our application you'll see why we've done this in a second but it's just required that we do it this way now we're going to go to urls.pi and we're going to set up a url for this auth url view so let's just go to another urls.pi file not this one actually let's go to frontend and let's just copy the existing contents so we get these imports in here already now go over to my other urls inside of spotify paste that inside remove that remove all this and we'll say path this is going to be slash get hyphen off hyphen url you could call this whatever you want but we'll just go with get off url and then we need to import so we'll say from dot views import auth url like that then here we're going to say auth url dot as underscore view now actually i just realized i have this slash here we can remove that but that's good that's all set up now what i need to do is add a url path for this spotify app from my main application url so let's go to musiccontroller urls.pi here you can see that we're including the frontend urls we also want to include the spotify urls we're going to say now if you go to spotify slash we're going to include spotify dot urls there we go so now we can actually hit and reach that um url endpoint okay great so now we have the endpoint that actually gives us a url now we're not done yet of course there's a lot more that we need to do the next thing that we need to do is set up a redirect uri this is also oftentimes referred to as a callback so essentially after we send the request to this url right here we need a callback or some url that this information gets returned to so again let's go back to this diagram make sure we understand so we're sending this request so let's say we're at this point right here then the user logs in they authorize their access then what's going to happen is we get returned code and state so what we need is some endpoint or some i guess a view or function or whatever you want to call it that can take in this code and do something with it so after we get the authorization access we then need to send another request and get the access and refresh token so that's what our callback needs to do so when we pass the redirect url after this is done it's going to send this information to the redirect url or uri anyways let's code out this function so i'm not going to make this an api view although we could make an api view but i'm not going to i'm going to say define spotify underscore callback like this and this is going to be equal to request and sorry it's going to have requests as a parameter and it's going to say format equals none then inside of here what i'm going to do is i'm going to get the pieces of information from this request that i want so the first thing that i want is the code this code is how we're actually going to authenticate our user our access story the refresh token and the access token so we're going to say code is equal to request.get.get and then we want code like that then we're going to say error is equal to request.get.get and error now we're actually not going to do anything with this error but i just wanted to show you how we can get this in case you want to see what the actual error message is if for some reason there is an error then we will get a response that does have an error tag in it or error information in that case we can read this error and you know maybe display it to the user and see what's actually going wrong anyways once we get this information now what we're going to do is send a request back to the spotify account service that says hey give me the access token and give me the refresh token so we're going to say response is equal to and we're going to use post which i imported up here from requests and inside of here we're going to post to https colon slash and then accounts dot spotify dot com slash api slash token again to find this url you would just have to look at the spotify documentation we're going to say data and inside of here we're going to pass all the data that we need so we're going to pass the client id the client secret the grant type the code and the redirect uri so inside of here let's go ahead and do this we're going to say grant underscore type and this is going to be equal to authorization underscore code like that because that's what we want then we're going to say code is equal to sorry the variable code that we had above then we're going to say that the redirect uri inside of a string underscore uri is equal to the redirect uri we're going to send now the client id and the client secret as well so client id client id and finally client underscore secret client underscore secret all right then we're going to get the json from this so sorry that needs to be in lower cases but by calling this post method right here we will actually automatically send the request and then we will get the response we'll convert that into json so that's different from here because we're not actually sending the request in this api we're simply generating a url so that we can then send the request to that url anyways you'll see when we use this it will start making sense but let's continue so now spotify callback after we do this what we want to do is we want to look at this response we want to get the access token and the refresh token and all the other information so we're going to say access underscore token is equal to response and we're just going to get like this the access underscore token then we're going to say the token underscore type is equal to response.get and token underscore type and you get the idea we're going to continue to do this for everything else so refresh underscore token it's equal to response.get and then refresh underscore token uh what else do we need we want the expires in so we're going to say expires underscore in is equal to response dot get expires underscore in okay that's great uh and then finally we'll get the error so we'll say error is equal to response dot get and then inside of here we will say error all right so now we've gotten the information that we want now the question is what do we do with this now so this is our callback so after we send the request to this url it will return the information to this function right here inside of this function we then send a request using the code to get access to the access token the refresh token all the other information that we want so now what we actually need to do is we need to store this token now keep in mind that we need to do this for multiple users right every single time a user creates a new room we need them to authenticate their spotify and hence we need to store multiple tokens tokens for each user that's on our website so what we're going to do is we're going to create a database that can actually store all of these tokens we're going to associate the user session key or their session id with their access token now keep in mind that we only need the access token for people that are hosts of the room so if we can do that if we can store all of the host access tokens and refresh tokens we're good we can use them whenever we want and then of course if they have a new session we'll have to get a new access token refresh token and all of that anyways the point of me saying this is that now we need to make a model so we're going to go to models.pi and just like we've done previously we're going to make a model that can store tokens so we're going to say class we're going to call this uh spotify token like that and we're going to take as the inheritance models dot model now inside of here we're going to say the user is going to be equal to models dot char field like that and we'll say the max underscore length is equal to 50 and unique is equal to true next we'll say created underscore act is equal to models.datetime field and we'll say auto add underscore uh auto sorry it's auto now underscore add equals true like that and then we'll do the refresh token so say refresh underscore token is equal to models dot char field max length equals 150 characters i don't think it's that long but just in case we got a really long one let's do that i'm going to copy this one more time for the access token so that and then we want to store it the expires underscore in so i'll be equal to models dot date time field and then we'll say the token underscore type is equal to the models dot char field with the max underscore length equal to 50. all right so that's the information that we want to store in this model but now since we made a change to our model we need to actually perform a migration so this is actually a good thing to show so let me just quit my web app now let's go over here and i'm going to just clear the screen so it's easier i'm going to say python manage dot pi and then make migrations like that so again whenever we make changes to our database or we add a new model we need to make migration so we say make migrations we should see migrations for api okay alter field okay that's not exactly what i wanted to do um all right let's try python manage.pi migrate like that and see what that one does so i realized i made a very small mistake here when we added the spotify app we forgot to add it to installed apps so when i just did this migration i guess i had made some minor change that's why something actually happened but it wasn't adding our new model and i was like what's going on the reason why i wasn't doing that is because i didn't add this app to our installed apps so let's go to music controller settings and let's add this in so what we need to do is just say spotify dot apps dot spotify and then config like that now once we add this to the installed apps if we run uh python manage.pi make migrations we should see that there we go create model spotify token then after we make the migrations we'll migrate and there we go so it performed the migrations and all was good all right so hopefully that makes sense you guys followed with that small mistake but now let's continue so now that we have this model what i want to do is as soon as i get access to this information i want to store it in the database so i want to store it in this spotify token model and what i'm going to do is i'm going to use the user let me go back to models here i'm going to use user right here i'm going to store their session key right just like we've done for the rooms i'm going to have user storing the session key so that way we can figure out which user is associated with each set of tokens okay awesome so let's go back to views and now we want to save these tokens so what i'm going to do because things are going to start to get a little bit messy here if we do everything in one file is i'm going to make a a new file inside of spotify here i'm going to call this util dot pi standing for utilities right so inside of here we're going to define a function and what this function is going to do is save our token so it's either going to save it in a brand new model or it's going to update an existing model with new tokens so i'm just going to call this define update underscore or underscore create underscore user underscore tokens and again the point of this is just to update or create user tokens and store them in the database the first thing i need is my session underscore key or my session id whatever i'll just call it session id but i think it's probably more appropriate as a session key then we'll say we want the access token that we would need to save we need the token underscore type pretty much everything that we had on the model we're going to have to take in here then we also need expires underscore in and finally we need our refresh token so then what we're going to do is we're going to say tokens is equal to and we're going to look to see if the existing user has any currently existing tokens so this leads me to another function that we're going to write which is called define get underscore user underscore tokens and inside of here we're just going to take the session underscore id now we're going to import our model from above so we're going to say from dot models import spotify oops spotify token like that and then we're going to say user underscore tokens is equal to spotify token dot objects dot filter and then user is equal to session id so just checking if we actually have any tokens associated with the specific user then we're going to say if user underscore tokens dot exists so if we do actually have any tokens here we'll return user tokens at index 0 because we know we'll only ever have one set of tokens for an existing user otherwise we'll return none so return none like that great so now we can use this function so we'll say tokens equals get user tokens session id is what we'll pass here and then we'll say expires in is equal to and i need to set something here so i kind of got ahead of myself i should have explained what's going on here but when we actually get the request back with these tokens so it's going to send us the access token the token type all this information right expires in is actually going to be a numeric value in fact it's going to be equal to 3 600. now this is telling us that your token is going to expire in 3600 seconds which is one hour so what we need to do is convert this into a time stamp because sure 3600 is useful to us but i don't want to just store 3600 right i want to store the time at which our token actually expires so i'm going to get the current time and then add an hour to it and store that in the database so that way it's really easy for me to check if the token's expired i don't need to do any other math i'm just storing the correct value in the database so to do this we need to actually import something we're going to say from django dot utils import and it's called time zone like this now for expires in what i'm going to do is say time zone dot now this will give us the current time that is related to the current time zone that we're in so we'll say time zone dot now plus time delta and i need to import time delta this is from date time so we're going to say from date time import time delta like that we're going to say seconds equals and then 3600 uh not 2600 sorry i shouldn't put 3600 here i should put expires underscore in okay so this since we know it's a numeric value and it's giving us the amount of seconds we say okay let's convert this number of seconds into a time delta this just allows us to add it to an actual timestamp then we'll add it to timezone.now and then we'll use that and store that in the database okay great so next we're going to say if tokens so if we actually do have tokens associated with the current user then rather than creating new tokens we're just going to update the existing ones we'll say tokens dot access token is equal to i guess this will be access token then we will say tokens dot refresh token is equal to the refresh token tokens dot expires underscore in is equal to expires in tokens dots what's the last one here token underscore type equals token type great then we're going to save this so we're going to say tokens dot save and we need to add the update field so let's say update underscore fields is equal to and we'll update the access token field we'll update the refresh underscore token field we'll update the expires underscore in field and finally the token type although the token type should stay the same um like when we're updating this then uh we will say else and under here rather than updating all this information we'll just create new tokens so we'll say tokens is equal to spotify token like that and then we'll say user is equal to the session id we'll say the access token is equal to the access token we'll say the refresh token is equal to the refresh token we'll say the token type is equal to the token type and finally let's say expires in equals expires in great then we'll say tokens.save and there we go we will have created that in the database now the reason i'm going through this quickly is just because i've already shown almost all of this syntax before in previous videos so if for some reason this is really confusing maybe consult some of the other videos anyways all we're doing again is just updating or creating a new token instance in the database awesome so now that we have this util.pi file done let's actually use this so let's go to our views.pi from inside of spotify and let's import these uh these functions so let's say from dot util import and then we want to import update or create user tokens great so now we will actually use that so let's go down into our spotify callback and let's call update or create user tokens now let's pass the information we need the first piece of information we need is actually the session key or the session id whatever you want to call it so to get that piece of information i'm going to copy in a code snippet we've seen many times now and that is this we're going to say if not request dot session dot exists and then request.session.sessionkey create it so just make sure that we do actually have a session key because if we don't then this is going to cause an error anyways then we will pass the request.session.sessionkey as the first argument and then we need to look at the other order and it's telling us right here access token token type expires in refresh token so access token the token type like that the expires in and finally the refresh token all right so let's use that and then we're almost done we're at the very end of this function what we want to do is return the redirect and we're going to redirect to our front end colon now i'll show you how this works in a second but we need to import the redirect function so let's go up here and then i believe this is from django.shortcuts we're going to import redirect i don't think we've used this before but this is just how we redirect to a different web page so i know this is a lot to comprehend at once but this is our spotify callback so let's let's go back to this diagram here it's going to pass the code to this function that we just wrote then what we're doing inside of this function is we're doing this step so step number two we're sending the client id the secret the grant type the code and the uri and requesting the access token the refresh tokens then it's returning those tokens to us we're storing those tokens in the database and then what we need to do after this step is we need to return back to our original application so the flow is from our front end we're going to call this api endpoint we are then going to take the url that's returned to us and we're going to redirect to that page then from there that url once the user is done authorizing us we'll redirect to this function right here then from this function we'll send the request for the tokens store the tokens and then redirect back to our original application so that's why i'm redirecting to front end colon now there's a lot there's yeah a lot more steps that we need to do here but anyways hopefully that's a good summary of what we've done so far so let's go to urls.pi now inside of spotify and let's set up a path for that thing that we just created so let's import the spotify callback we also could call this redirect whatever it doesn't matter i'm just going to say path i'm going to call this redirect and then i'm going to say that this is just going to hit this function which is spotify callback great so i don't think uh yeah i think i did show you guys how this worked at the beginning of the tutorial series anyways uh this is just a different type of view right so we're just redirecting to a different page from this view now notice i'm doing front end colon so the way this works is that if we want to redirect to a different app right because right now i'm inside of the spotify application if i want to redirect to a page inside of the front-end application which is what i want to do i put the name of the application colon and then the page that i want to go to so if i want to go to the room page i would go room like that but all i actually want to do here is just redirect back to the home page because we've already set it up so that the home page will redirect us to the correct page if we're already in a room right so if i just go to the front end home page then i know i'm going to end up going to the right place anyways to make this work what you need to do is go inside of the urls.pi file for your frontend so go inside of frontend to urls.pi and you need to add a variable up here called app underscore name and set it equal to the frontend so or you can set equal to whatever you want but frontend is the correct name the reason we're doing this is because django needs to know that this urls.pi file belongs to the frontend app it can determine that because the folder it's in but this is just something that's required to put inside of here so that that method i just showed you actually works we also need to go inside a path we need to name our path so i'm going to say name is equal to and just an empty string the reason for this is because right now we don't actually have a way of identifying all of these paths sure we can look at you know the name of the actual path but we need to give it a formal name so that when we call the redirect function we know which path we should actually go to in theory i could name this hello and then if i redirected to frontend colon hello it would bring me to the empty string path so anyways let's just leave it empty string so that makes sense but now our redirect should actually work okay so now that we have that let's see what we need to do next okay so i was going to jump over the front end but i realized that it probably makes more sense just do all the back end stuff first and then go over there so we need to write a few more functions here that that have some specific purpose the first one is to check if a user is currently authenticated so obviously we don't want to keep asking the user to authenticate if they're already authenticated so we need something that can tell us well if they're authenticated so let's go to util.pi and the nice thing is that now that we have these tokens stored in a database we can just check if the current session id so representing the user is in the database and if the token is expired or not if the token's not expired they're authenticated if it is expired we need to refresh it so let's write a function i'm going to call this one is spotify underscore authenticated like that we're going to take the session id now maybe we just call it is authenticated but let's just be more specific and put spotify there and inside of here what i'm going to do is check if the current session id so the user is authenticated so we'll say tokens equals and then get underscore user underscore tokens that function that we wrote up here we'll pass the session underscore id and then we'll just do a quick if statement and say if tokens so if tokens what we're going to do is say date is equal to tokens dot expires in in fact maybe we'll call this expiry because that probably makes a bit more sense so we'll say expiry like that and then if expiry because remember this is a date time object is less than or equal to the current time zone dot now we already imported this from above then what we need to do is refresh this token so we're pretty much saying if the current expiry has passed right if the current time has passed the expiry let's refresh this token then otherwise so let's just fill this if statement here actually i don't even need the else i can just say return false like that because you know if we don't have any tokens then we are not authenticated if we didn't get something from the database we are not authenticated so we return false and then here we need to actually refresh the token so i'm going to write another function now i'm going to say define renew or we call it refresh underscore spotify underscore token okay so inside of here we're going to send the requests that we need to use to actually refresh our token unfortunately they don't have this request in that nice little drawing otherwise i would walk you through why i've kind of picked the stuff that i have but just trust me this is how you actually refresh it and anyways it's not too difficult we've kind of done this already the first thing i'm going to do is i'm going to say tokens is equal to and then get user token session id um you know maybe if we want to save some time here we could just pass the token so let's actually just say tokens like that and here inside this if statement we'll call refresh spotify no refresh underscore spotify token and we'll just pass it the tokens now when i'm saying tokens i'm really just talking about that model object right that is storing the tokens that's what's being returned here i'm just calling it tokens because it does have multiple tokens in it anyways we have tokens so we're going to say that the refresh token which is the one we really need here is equal to tokens dot refresh token again remember this is just the model so we have refresh token access token expiry token so on so forth then what we're going to do is we're going to say response is equal to post and here we're going to post to https colon slash accounts dot spotify.com api token this is the same one that we've used previously and then we're going to say data is equal to we're going to send some information now what we need to send here is the following so the grant type is going to be equal to our refresh token so this is saying what do we want what do we want we want a refresh token or what are we sending sorry we're sending the refresh token mybad and if we looked at the other grant type where was the other grant type is it in this file or is it in in views let's have a look yeah okay so authorization code right so we're pretty much telling it what to expect here we're saying yeah we're sending an authorization code and here we're saying we're sending a refresh token so my bad okay and then we're going to say the actual refresh token is equal to the refresh token then we want to send the client id so we'll say the client underscore id is equal to the client id which i think i have imported no i don't have it imported so let's import that from above so from dot credentials import client underscore id client underscore secret like that okay so we'll send the client id and then finally we'll send the client underscore secret so client secret like that great so now we have that information uh post okay that's fine undefined variable oh i guess i didn't import post sorry guys let's go to the top and import post so let's say from request import post okay so post should be good now awesome we'll just convert this into json because that will actually give us the response and we'll say the new access token is equal to the response dot get we're going to get the access underscore token so again this is returning to us a new access token and a new refresh token that we can use for our api okay so there we go next we'll say the token underscore type is equal to response dot gets the token type this may seem uh not important or that we don't have to do this because the token type really should stay the same all the time but in case spotify decides to change something in the future it just makes sense to do this and then we'll say expires in is equal to response dot get and we will get the expires hyphen in and then lastly we'll say the refresh underscore token is equal to the response dot get refresh token okay great so now we have all that information and lastly we will call our update or create user tokens and inside of here we'll just pass everything so we'll start ah so here this is the issue this is where i need my session id because i need to pass my session id to my update or create user token so anyways we'll pass session id we'll change inside of here to be session id and then for our refresh token this will have to be equal to get user tokens we're going to have to pass the session id dot and then refresh token and then sorry up here we're going to have to change tokens to be session id okay so hopefully you guys see the changes there we're just changing the parameter and that required a few other small changes anyways we're going to say update or create user token i'm going to pass the session id i'm gonna pass the new access token the token type the expires in and the new refresh token uh come on why is refresh token not showing up did i spell something wrong refresh token okay i think that is good all right uh oh sorry this should be a string my bad guys string needs to go inside of this get okay so that's actually it for refreshing the spotify token so now what we'll do is while we've already had this here after we refresh the spotify token we will return true so this is just checking so okay do we have a token if we don't return false because we're not authenticated if we have a token but it's expired then we are authenticated we just need to refresh the token so let's do that and then after we do that we're all good we can return true now of course if this isn't true that just means that we have a non-expired refresh token so we just return true awesome so now one last thing that we need to do here we need to set up a view that can actually tell us whether or not we are authenticated so this util right is returning true or false this is python code but we need to return some json that our front end can actually understand so let's go to views.pi and let's make one more function here and in fact we can make this a class we'll say class is authenticated like that this will inherit from the api view and we'll define a get method so to find get self request and optional format equal to none now inside of here what we're going to do is we're going to call this util function which is is spotify authenticated and we'll just return some json response to whoever's sending this to us telling us whether you're authenticated or not okay so we're going to say is underscore authenticated is equal to and then we need to import from up here is spotify authenticated so we'll call the is underscore spotify authenticated we'll pass in here the req sorry not request the self dot request dot session dot session key that's all we need for that and then what we can do is simply return a response so we'll say return response inside of here we will say i guess status is equal to and then is underscore authenticated and then we'll say the status is equal to status.http underscore 200 underscore okay all right so pretty straightforward but this is just going to be an endpoint that we can hit that will tell us whether or not we are authenticated so let's go to urls.pi and let's set up the actual endpoint for this so let's import this we'll say is authenticated and then we want to return a path and we'll just say is hyphen authenticated and we'll say is authenticated.as view all right so at this point in time the backend is done there's a few minor things we're going to do in the future but that's fine we'll continue moving on for right now and i understand this video is getting long if you guys are here congratulations hopefully everything's making sense and again code link in the description in case i'm going too fast for you so let's go to components now inside of our front end app we're going to go to room.js so the idea here is that as soon as we get into a room if we are the host of this room then what we need to do is immediately authenticate our spotify right because we need a way to actually control the music so if the user is a host and the user enters this room then we need to check if they have authenticated with spotify if they have not we need to actually authenticate them right so we need to show them that web page that has the prompt and then they need to you know give us the authorization or whatever it is we need to take the tokens store them in the database and then all will be good but this needs to be handled from the front end at least a part of this so the first thing i'm going to do is just add a variable to the state i'm just going to call this spotify authenticated and this will be equal to false then i'm going to make a method i'm going to call this authenticate spotify so authenticate spotify like that and inside of here we're going to send a request to our backend we're going to ask if the current user is authenticated but only in the situation where this user is a host now what that means is that we need to wait until this get room details function has run before we call this method so inside of this dot then is actually where i'm going to call this so after we set the state then what i'm going to do is call this dot authenticate oops this dot authenticate spotify but i'm only going to call this if the user is the host so we'll say if this dot state dot is host then we can call this right here suite okay so that is what we'll do then inside of authenticate spotify we will send the request so inside of here i'm just going to say fetch and we're going to fetch the slash spotify slash is hyphen authenticated if i can spell this correctly this is a large word okay fetch spotify is authenticated now we will say dot then and we will take our response like that and we will simply return response dot json now we know that we're never going to have an invalid response because all we're ever doing is just returning true or false then we'll add another dot then and we'll say then data and then we will do something with this data so what are we going to do with the data well we're going to start by setting the state of whatever was returned to us so whether the user is authenticate or not so we're going to say this dot set state and inside of here we're going to say uh i guess what do we even call this spotify authenticated and then i guess this is going to be colon data dot status because remember status is what we returned as the key that held either true or false for whether the user was authenticated now after this this is where it gets interesting if the user is not authenticated we need to authenticate them so we're going to say if not data dot status so then inside of here what we'll do is we'll say fetch and we will fetch the url that we're going to use to authenticate so slash spotify slash get hyphen auth hyphen url then we will say dot then and we will take the response and simply return the oops the response dot json like that then we'll say dot then again and we'll say dot then and data is equal to and we're gonna do something interesting inside of here so let me pause for one second so now at this point data is going to be equal to or sorry data dot url is going to be equal to the url that we need to use to authenticate so pretty much what happens is let's go to views again if we have a look at spotify callback or sorry not spotify callback but auth url we see that we just return the url right so the key url gives us the url and the url will be prepared by this statement right here so we will visit that url and then when we visit that url we'll have the user authenticate their spotify account so that's like what we're going to do inside of here so to do that we need to say window dot location dot replace and this is another way to do a redirect that is not like involved in react like this is native to javascript so we'll say window.location.replace and inside of brackets we're going to say data.url so what this will do is redirect us to this spotify authorization page then from here after the user authorizes us it will redirect us to the spotify callback so the spotify callback will save the token and redirect us to the front end and then the front end will redirect us back to the room page so that is kind of what's going on here hopefully that makes sense but that's what this will do now there's one thing we need to do we need to bind this method to this keyword so let's just quickly do that we'll say this dot i guess what is it what do we even call this authenticate spotify is equal to this dot authenticate spotify and then dot bind to the this keyword okay so now that that is bound to this keyword this should work okay so i'm jumping in here at kind of a random point i apologize for the strange transition but i had messed a few things up in anyways i just have to come back here so the last thing we need to do because i just realized we forgot to do this before we actually test this application so we need to set the redirect uri otherwise it's going to run into an issue so let's set the redirect uri and just as a reminder we should set this to slash spotify slash redirect because that's where we want to go after we authenticate or authorize our application so let's go to the credentials and let's set this to http colon slash and then 127.0.0.1 spotify slash redirect all right so now what will happen is after we hit the spotify authorization page we'll redirect to slash redirect which as a refresher is this right here the spotify callback and then this will redirect us to the home page and all should be good so let's try this now but actually this reminds me i have this page open we need to go to our spotify dashboard so our developer dashboard we need to go to edit settings on our project and we need to authorize this redirect url so we just need to add the same thing we just wrote in redirect uris inside of the settings of our app so let's go to settings let's go to redirect http 127.0.0.1 sorry this is colon8000 bad we'll have to add that to the other one and then slash spotify slash redirect and then we'll press add so that should be good now let's just go back here and let's add the colon 8000 because i forgot that so coin 8000 let's save that there and now we can try to run this so again i apologize this is a lot before we run anything but this is really what we need to do before we could even test this so now i'm going to go to 127 and okay we're now inside the room page now i'm just going to clear my cache here and reset this so that we can test this from the beginning let's go to create room let's press create room and then boom we get inside of the room but for some reason it doesn't ask us to authorize with spotify and okay that would be because we're already getting true because i had messed with this previously anyways to test this out again i'm just going to go to an incognito window and we'll go now into the app i'm going to go create a room and ready let's press create a room and let's pray that this works okay boom there we go it redirects us to the spotify page here not the cleanest redirect in the world but it did bring us there and now i'm just going to sign into my spotify account i'm going to skip over this because obviously i don't want you guys to see my credentials and then we will continue okay there we go so i just signed in i pressed authorize and then it brought me back to this page now i did actually just print something out so we could see but let's go to console we can see that this true here is telling us that we are indeed authorized all right guys so with that i'm going to leave the video here in the next video we'll do more with this spotify api we'll actually set up a nice interface so we can view the current song fast forward play pause all of that anyways i hope you guys enjoyed if you did make sure to leave a like subscribe to the channel and i will see you in another youtube [Music] video you
Info
Channel: Tech With Tim
Views: 23,911
Rating: 4.9577041 out of 5
Keywords: tech with tim, django and react, spotify api python, spotify api, spotify api project, python spotify api tutorial, spotify api tutorial, spotify api tutorial react, spotify api authorization, spotify api access token, django and react tutorial, react, django, react tutorial, django tutorial
Id: rYDDWVuv-kI
Channel Id: undefined
Length: 57min 57sec (3477 seconds)
Published: Fri Dec 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.