Getting started with Laravel Passport and OAuth2

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Hey everyone! Andrew here, again.

Not sure what it was about OAuth2 and Passport, but they always seemed kind of complicated and hard to wrap my head around. I decided to put together this basic getting started guide to try and remove those barriers and introduce you to this pretty powerful package and authentication flow.

This tutorial definitely doesn't cover everything, it's pretty pared down and should just give you enough to get started with OAuth2 and Passport. If there's more demand for it, I'd be happy to do something more in-depth in the future!

👍︎︎ 12 👤︎︎ u/aschmelyun 📅︎︎ May 11 2021 🗫︎ replies

Awesome :)

👍︎︎ 3 👤︎︎ u/NoDadYouShutUp 📅︎︎ May 11 2021 🗫︎ replies

Really love your videos man! Keep up the good work :)

👍︎︎ 3 👤︎︎ u/[deleted] 📅︎︎ May 12 2021 🗫︎ replies

Hi! I watched the video and this is better than other videos,can you create something with JWT too?

👍︎︎ 2 👤︎︎ u/pldc_bulok 📅︎︎ May 12 2021 🗫︎ replies

This is actually pretty good, subscribed!

Your keyboard is a bit loud sometimes but other then that good explanation, good voice to listen to.

👍︎︎ 1 👤︎︎ u/[deleted] 📅︎︎ May 12 2021 🗫︎ replies

OMG, just what i was looking for! You Ser, came just the right time!

👍︎︎ 1 👤︎︎ u/FucacimaKamakrazee 📅︎︎ May 12 2021 🗫︎ replies

Great stuff, Andrew!

👍︎︎ 1 👤︎︎ u/lyotox 📅︎︎ May 12 2021 🗫︎ replies
Captions
hey everyone andrew here this video is the last of my three-part series on laravel's current authentication ecosystem exclusively covering the passport package if we take a look at the documentation page passport provides a full oauth 2 server implementation for your larval application in a matter of minutes if you're unsure what that means or don't have experience with oauth 2 you can find it used whenever you sign into a web app using some kind of other external service for example if i was to sign in with github on this platform i'm prompted with a pop-up detailing what information that github will allow them to access after i hit this authorize button they're given an authentication token that they use to retrieve the information that i've approved from github and build my profile off of it this is what we can implement on our larval app with passport with our application acting as github in this scenario alright let's get started i have here a laravel application that i've set up already i've also created a test route and seeded it with a little bit of data like a blog there's posts and each one is attributed to a specific user through their name however we don't know which one of these is ours what i'd like to do is create a way for a third party application to request an authenticated user's email address and posts through a secure oauth2 api using passport and maybe even be able to create some new posts for them as well before we install this package you'll notice this section on the documentation titled passport or sanctum sanctum as you might know is another official larval package for authenticating with session cookies or bearer tokens i covered it in a previous video which you can check out here if you'd like what your decision should boil down to is how you or others plan on using your applications api if it's going to be called by something like a companion single page application or a mobile application it might be better to stick with sanctum setting it up is pretty straightforward it works out of the box with spas on the same domain and creating and managing authentication tokens doesn't take much work there are some downsides though particularly if you'd like to gate and alert your end users as to what data will be passed to a third-party application having them approve it first if that increased security sounds like something you'd want it might be better to continue with passport alright now that that's out of the way let's get started actually installing it so from our command line at the project root we'll have to run composer require laravel passport and once that finishes up we'll need to run the migrations using artisan now my local environment here is using docker so you'll see for artisan commands i'll be using the dcr command which is a short code on my system for docker compose run and finally we'll have to run an artisan command passport install to get the scaffolding for passport setup okay that looks like it went through well so our next step will be to take a few lines of code and add them to our user model and routes for the user model we'll need to implement the laravel passport has api tokens trade and in the auth service provider class we'll have to call this passport's routes static method which will scaffold out all the necessary endpoints that we need finally at the bottom of our config auth file we'll have to change the api driver from token to passport okay now this should be everything that we need to install in order for our users to start using passport what they'll have to do though is create a client which is an application that they intend to call this api from using our analogy earlier if we are github then the client would be the site that i'm trying to connect with or log in with github in order to view and create a user's clients passport has a few options out of the box we can either use this artisan passport client command which we can run in our terminal there's also this json api that passport provides to us as well instead of utilizing that client command we can use a few endpoints to create a front-end and help manage our users clients the api though is guarded by both web and off middlewares so it can only be called from our own application and not from an external source we're going to take a slightly different approach here by using the same endpoints and methods we'll be able to list and create new clients for our particular user heading back into our laravel app i've already taken the liberty of installing breeze which is an authentication starter kit for laravel this allows us to easily register or sign a user in and provides a pretty small dashboard starter kit let me just register a new user real quick hit register and we're in the dashboard what i'd like to do next is create a new route that'll show the clients associated with our user and give them a form in order to create a new one first i'm going to copy this dashboard blade template to clients.blade.php and i'm just going to scaffold out something basic with the included tailwind css library that breeze provides and now we'll also need a route and controller method in order to display this view and the client's data associated with it in our routes web file we'll create a new one called clients actually dashboard clients and in the view we'll also return all of the clients associated with this particular user all that's left to do is add this new route to our navigation header all right let's head back to our browser refresh and try it out well we have no clients so this is exactly what we're expecting but what i'd also like to do is add on this page a form in order to create a new client so let's create another one of these cards and create a form whose action is going to be oauth clients this route correlates to the one that's in the passport documentation and should allow us to easily create a new client whenever the correct information is passed through for that we will need two things a name and a redirection url [Music] [Music] let's refresh and it's it's all right but let's clean it up a little bit more okay that's slightly better it's what we can work with so now what we should be able to do is create a new client with a name my client and a redirect url which is what the user will be sent back to whenever they've authenticated against our application so for this let's call it laravel app dot test callback hit create client and we've gotten back our client with a secret and a redirect url now normally this would be called through some kind of asynchronous method like axios or fetch purely for the sake of simplicity and time i've called this directly through a form on the dashboard so all we have to do then is go back to our dashboard clients route and we now see that we have a client along with a callback url for it we'll also probably want to display that secret just in case somebody needs to see it more than once so underneath our redirect we'll also call client secret so now if we go back to our browser and refresh we'll see the secret underneath the client as well which we'll need in order to authenticate against our api at this point this is basically all we need in order to get started with authenticating against this api so what is this laravel app.test well it's another external application it could use laravel but it could be a vanilla php project a wordpress site a mobile app or anything that will be needing data from our api again calling our analogy from earlier if the application that we just worked on and set this up on is github then this laravel app.test callback route is what's going to allow our users to sign in with our larval application and let us get guarded api data back from it instead of creating a separate laravel app to show you the authentication procedure i'm going to be doing everything inside of postman the reason for this while it might be a little confusing is that i would like to keep this tutorial as platform agnostic as possible i would like you to be able to use the knowledge here on a laravel app as well as a mobile application a view spa or any other platform that you might need to call an authenticated api from the first thing that we need to do is call the oauth authorize route to this we'll have to add a few query variables the client id the redirect uri a response type set to code a scope set to empty and state for the client id and redirect uri we already know these in our application our redirect is laravel app dot test callback and our client id we can make up here by adding another line to our clients at blade template client id and each of these i'm going to prefix with what they actually are okay that's a little better so our client id is 3 and now all we need is a state if we look at the laravel passport documentation a state is defined as just a random string of 40 characters that we keep in a session the reason for that is that after the authentication takes place is that we use the state variable to determine if the request is authentic so for now i'm going to use a state that's pretty easy to memorize i'm going to use asdf 10 times [Music] all right now if we hit send for this and preview we get back a login form since we are not logged into the application in postman so let's log in with the user that we want to authenticate against our one that we created earlier hit login okay maybe this isn't going to work well in postman for this instead let's copy this whole url and open it up in our browser because we're already authenticated it's now displaying the screen that was showing when we tried to log in with github earlier it also looks like it's a little unstyled but that's because right now passport's still using bootstrap classes when our application is using tailwind css because of the breeze installation you can publish these views and edit the styles or the classes yourself through an artisan command for right now this works for me and we have two options authorize or cancel so my client is our client name that's pulled in automatically and it's requesting permission to access my account on laravelpassport.test if we hit authorize what that's going to do is send us to our redirect url with a token that token will be used in another call to actually create the authentication token so that we can start grabbing data from our api let's hit authorize and we get an error back that the site can't be reached which is understandable i mean we don't have laravel app.test up and running right now but what we do have is this code right here what we're going to do is copy this and we're going to use this in subsequent calls in postman to actually get our authorization token so now what we have to do is call a new route as a post request we have to call our laravel our laravel passport.test app oauth token we'll send this over as form data and we need to include a few variables grant type as authorization code client id as the same id of our client from earlier three client secret which we can copy over later from our application redirect uri which is the same uri that we were on earlier larval app.testcallback and code which was the code given back to us earlier this long string let's copy over our client secret real quick [Music] and when we hit the send button we get a request back that includes what our token type is when it expires and the full access and refresh tokens using this access token we can now make calls to our applications api as an authenticated user we can get back user information we can create posts on behalf of that user and we can do anything that we need to just like an authenticated user on the front end let's copy this token so to test this out we can use a route that actually already exists https laravel passport.test api user if we take a look at our api.php file we have this user route already defined by default in larval applications and it's using the auth api middleware which means that it's only available to authenticated users if we go to the authorization tab and we click bearer token we can paste in our token that we were given back earlier and make this call getting back our user id and name but it doesn't include our email we want to hide the email addresses of users when they're being displayed through the public api but through a private api we would like to show that information and you can actually do that very simply with laravel on the user return request we can tack on make visible which asks for an array of attributes that are currently hidden that you would like to display in this particular instance so for us that'll be email if we go back to postman and refresh you can now see that our email attribute is displayed but if we call the public posts api that we were looking at earlier each user still only displays the id and name associated with them now let's try using this api to create a post on behalf of our user so we can create a new route in the api.php file following the same convention as the route above it route middleware off api get posts new function request request and we're going to return request user posts create request only title and content kind of a long chain but it's pretty straightforward for our request user and the post relationship that's associated with them we're going to create a new eloquent model and only pass in two attributes from our request array title and content normally we want to validate these before they're actually added into the model but for this test i don't feel like there's really a need to do that back in postman let's add a new route post laravelpassport.test api posts new add in our bearer token authorization which is already set from the last tab and in the body we're going to include title my cool new post content look at this cool post i made it myself and if we hit send the post method is not allowed for this route ah i didn't get here this should be a post save and also what we're going to need to do is in our headers we should say accept application json so that we get back the appropriate response instead of a blob of html so now if we hit send on this we get back our object which is a title content user id and post id and if we go back to our browser and view this post object again we can scroll to the bottom see our new posts and the user who created it ours authenticated by the api if we go back to the original response from passport when we got our authorization token we can see this expires in attribute here what this is is the number of seconds that this token lives for so it looks like right now we have 31 million 536 000 seconds which equates to exactly one year that's pretty long for these tokens sometimes applications would like them to be that long sometimes applications would like them to be shorter maybe just a day or two or even a few hours long for that you're probably going to want to refresh the token fairly frequently in order to make sure that your user doesn't have to continuously log in or authorize your application against subsequent calls with passport that's fairly simple all we need is this refresh token here and we have to make a call again to this oauth token endpoint in our application that's using passport for the grant type we change this to refresh token and then instead of code we have refresh token and the token that was provided to us now if we hit send we get back another token with the same expiration time a new access token string and a new refresh token string as well now unfortunately this does invalidate our previous token so if we go back to this get request that was using that previous token and hit send we are now seeing a box that will require us to log into the application before viewing it and that's actually because we haven't set the accepts header for application json if we do that and hit send again we just get back a message that says unauthenticated but if you're doing this from a plain http call you'll get a redirect to the login screen for your laravel application that uses passport but we can just copy this new authentication token paste it into our authorization and everything works again just as expected there is one more thing that i would like to demonstrate with passport and that's creating scopes for your clients and for your authorization tokens if we take a look at the passport documentation there's a section called token scopes what a scope is is it allows clients to request a specific set of permissions when requesting authorization to access an account so for instance with our application let's say we want to get back the user's email address to create a profile for them but we don't want an application to be able to create posts for that user we can use scopes to do that so back in our auth service provider class we can add this passport tokenscan call which expects an array consisting of identifiers for the scopes and definitions for each scope let's head into our code and add that now so we have two types of scopes that we can use get email and create posts so the get email scope can retrieve the email associated with your accounts and the create postscope can create posts on behalf of your user so now using the same client that we had created earlier if we head into postman in the original tab that we were calling this authorization for we can change this scope from a blank string to get email now if we copy this link and open it up in the browser we can see here now that we have this new line that says this application will be able to so when i hit authorize the code that's generated whenever it's called in the api can only retrieve emails associated with my account it cannot create posts on my behalf we can actually change that scope in here from get email to create posts and it'll now say it can't access my email anymore but it can create posts on my behalf and we can actually separate more than one by a space so we can do create posts percent 20 get email and now we see we can both create posts on behalf of my user and retrieve the email associated with my account for this though i don't want to be able to have this application create posts on my behalf i just want them to be able to get my email address associated with the user who's logged in so let's authorize it and we have the callback code copy it over and instead of refresh token we're going to do code paste in our code and instead of refresh token we have authorization code hit send and we get back our access token now this token as it stands right now will let us do both of these things still it'll let us create a post and it'll also let us get an email address but we want to be able to gate this so that this token and any subsequent tokens made moving forward can only show email addresses and not create posts on behalf of the user in order to do that if we head back to the passport documentation all we have to do now is check the scope in the middleware with this scope's colon helper in our routes.api file we can call two middlewares now auth api and scopes getemail for this and then for our post new route off api scopes create posts so now if we save this and try to access our api again oh we forgot one step we need to add these scopes and scope middlewares to the kernel.php file and there we go we can see that we're still getting back our user with the email address because that authentication token is in our scope but if we try to create a new post for our user using this same token [Music] and let's change the body of the post a little bit and if we hit send on this we get back a message saying invalid scopes provided along with the whole trace for the exception so this request was blocked a 403 forbidden was given back as the response code and we cannot proceed with creating a post for our user with this token alright that's about it for this video there's more to passport than i mentioned here like pkce or personal access tokens but this should be a good base for a lot of use cases with this incredible package oauth 2 can be a complicated and complex standard so i hope i've helped pave the way for learning more about this versatile and useful method for authenticating your apis huge thanks to my github and patreon sponsors youtube elite members and everybody else who continues to support these videos as always if you have any questions about this or any other web development topics please feel free to reach out to me in the comments or on my twitter linked below thanks for watching
Info
Channel: Andrew Schmelyun
Views: 13,218
Rating: undefined out of 5
Keywords: laravel, laravel api, laravel passport, laravel passport authentication, laravel passport tutorial, laravel passport tutorials, laravel postman, laravel tutorial, oauth 2.0, oauth2 authentication, oauth2 laravel, passport oauth, php oauth2 tutorial, php tutorial, postman oauth, postman tutorials, token based authentication with laravel, what is oauth
Id: PTFPMAX_88s
Channel Id: undefined
Length: 29min 52sec (1792 seconds)
Published: Tue May 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.