Laravel SPA Authentication - setup and common mistakes

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
and this is the part where we get angry like what the hell is going on I have everything properly configured why do I get a for one response this is frustrating however in this video I'm going to show you step by step how I personally set up larville for a space authentication now between steps I'll stop and discuss some of the most common mistakes I see people make that said let's start with the first mistake or misunderstanding your SBA and larval API must be on the same top level domain you cannot have your SBA on domaina.com and API on domain b.com the reason for this is because larval sanctum which is the recommended laravel authentication package for sbas works by setting up an HTTP only lacks cookie this cookie is secure it cannot be read or stolen but more importantly it cannot be shared across different domains and this is why we need to have our front end and back end on the same top level domain usually you would have a subdomain either for the SBA or for the larville API as an example in this video we'll pair a view Spa with a laravel API so let's start by creating the view app we'll do npm init View at latest and hit enter then it will ask us for a project name let's say sba.sanctum if we want typescript no j6 no view router no pinga no and no no no let's see the into our app so I'll do cdspa dot Sanctum or on npm install and then npm run Dev to start it as you can see our vspa will run at HTTP localhost Port 5173 now let's put this aside for a minute and create our laravel application I'll sit into sites which is where I keep all my projects and create a new laravel application using the laravel installer so I'll do laravel new Sanctum I'll see the inter Sanctum and then I will initialize a new git Repository add all the files and set an initial commit and then what I will do is require laravel Breeze larville Breeze is the easiest way to scaffold a larval API application so we'll do composer require laravel Breeze to scaffold a laravel API application we can run PHP Artisan Breeze install and then API when running the install API command Breeze does a couple of useful changes we can use git status and git div to check them out so let's do git status as you can see Breeze deleted pretty much all our front-end related files we no longer have a package.json file app CSS JavaScript blade files not even the vidconfig file another thing it did is it added auth related routes controllers and tests finally it also pre-configured some of laravel sanctum's settings if you want to take an even closer look to what changed you can use the git div command you can do git diff and then pass the path to the file you want to inspect let's say config slash course.php and here are the changes breeze made anyway let's open up this in phpstore the first thing I'm going to do is configure the database connection so I'll open my EnV file and I already have a database but it's not called sanctum it's API I'll save this and then I'll open database seater and uncomment the test user so we have a user to test with finally I'll migrate the database using PHP Artisan migrate fresh and then seed let's run the application using PHP Artisan serve and we encountered our first small problem the application runs at HTTP 127.0.0.1 Port 8000 but the View application is on localhost 5173 and as you might remember both the spa and laravel API need to live on the same top level domain the good news is that localhost actually points to 127.0.0.1 so if you go in the browser to localhost Port 8000 we'll see our laravel application and our viewer app is on localhost 5173 so both applications run on the same top level domain the only difference is the port the next thing we need to do is configure course but before we start let's talk a bit about what course actually is because some people are still confused by this term so when a browser makes an Ajax request from one origin to a different origin we call that a cross-origin request and by default browsers block this kind of requests course which is short for cross-origin resource sharing is an HTTP header based mechanism that allows a server to specify any Origins other than its own from which a browser should allow making requests so we can configure our server to allow requests from other Origins but what is an origin anyway An Origin is defined by the scheme host and Port if specified so when comparing two URLs if any of these three parts are different drls are considered to have a different origin so in our case we have the API running on HTTP localhost Port 8000 and Spa on HTTP localhost Port 5173 so the scheme is the same the host is the same but the port is different this means these two are different Origins back to our laravel application we can configure cores inside the course.phpconfig file the breeze install command already did a good job configuring some of these settings but in any case let's go through them one by one and explain what they do this Pass Key specifies which larval route paths can accept cross-origin requests this star right here means all so all paths will accept cross-origin requests then we have allowed methods and this says what kind of HTTP methods can be received so posts put delete and so on allowed Origins and this is super important specifies what Origins are allowed to send requests to our larval application we also have allowed origin patterns and here you can specify a regex pattern that match the origins allowed headers are what headers are allowed to be sent in while exposed headers are the headers we want to expose to JavaScript Max H is used to Cache PreFlight requests a pre-flight request is a request a browser makes to ask the server for permission before sending in a cross origin request and finally we have support credentials set to true and this tells laravel to share cookies with the SBA where most people go wrong here is with the paths and allowed Origins here you must either manually enter all the allowed paths and you can also use something like API star and this basically will match all the paths starting with API or you can just leave in the star and allow all paths to receive cross origin requests as for the allowed Origins one common mistake I see is entering the origin with a trailing slash this will not work the origin must only include the scheme the host and the port if specified so no trailing slash otherwise it won't work so let's go to our EnV file and update the front-end URL I'll open the NV scroll up here we have front-end URL set to http localhost Port 3000 but we actually need 5173 so let's update that by 173 and remember no slash it will not work with a slash next up we need to configure our cookie domain if you open your session config file and scroll down you'll see we have a key called domain set to or EnV session domain so let's grab this go to our EMD file add it in and here we need to enter the cookie domain when setting this make sure you do not include the URL scheme or the port or a trailing slash so if you do something like this it will not work if you do something like this it will not work if you do this it will work if you do this it will not work so only include the host name or the domain say we have something like tallpad.com however there is something even worse than setting in the wrong session domain let me show you here I have another view app but this time I have it set up under a subdomain so aspa.example.test I'm confident I have everything properly set up so I'll go ahead and try to authenticate I'll do test at example.com and then password when I click login however I receive a 4019 error this means we are not sending the correct csrf token but if we look at the network tab we see that the sanctum csrf cookie request was successful so we should have the correct cookies if we go to the application tab under cookies we don't have any cookies so what the hell happened then we remember hey I forgot to set the cookie domain so I go to my EnV file and here you can see I have everything set up I have the correct app URL the correct front-end URL but I'm missing the session domain so let's add it I'll do session domain equals example DOT test so here we need to enter the top level domain if we go back and try to log in again we now get a 401 response which means we managed to log in but the subsequent request grabbing the user details failed because it couldn't be authenticated if we check the cookies here they are they are properly set up and this is the part where we get angry like what the hell is going on I have everything properly configured why do I get a for one response this is frustrating however if we are to go to the top level domain so example.test and inspect the cookies we'll see that we have two pairs of cookies one for the top level domain and another one that allows cookies to be shared on subdomains and that's why you get the 401 if we are to remove these cookies go back and try again the request is successful so this is a painful example where things can go wrong when configuring laravel for SP authentication so if you somehow receive for one errors and you have no idea why please check the top level domain cookies for duplicates back to our initial setup here the last thing we need to do is make sure the stateful domains are set if we open up the sanctum config file we see we have the stateful key right here that is set to an array determined based on the sanctum stateful domain's e and V value so let's grab this paste it here and set it to localhost Port 5173 the stateful domains were pretty much the same as the course allowed Origins if the domain sending the request is not part of the stateful domains list the request won't be authenticated moving on let's open up our view Spa add a login form and attempt to authenticate our test user but before we do anything let's make sure we install axios so I'll do npm install axios access is great because it does some nice things out of the box like taking the csrf cookie and set it as a header when sending request or laravel API if we were to use fetch or something else we'd have to do that manually so now I'll go to the app component and let's say we'd have a form which is a reactive value that is an object with email and password down here we'll replace the welcome component with the form that calls an online function and of course it has the email and passwordless Fields plus a login button let's add the login function the first thing we need to do here is called the sanctum csrf cookie endpoint this will set a cookie with a csrf token axios can then use for subsequent requests so we'll do a weight axios.get http localhost Port 8000 sanctum slash csrf cookie let's make this function a sync and then what we need to do is call the login endpoint with our email and password so we'll do a weight axis post and let's grab this will have login and we need to send our email and password so email is form.value.email and password finally to test that our authentication worked we'll call the API user endpoint which will give us the currently authenticated user details so here we'll do access get localhost 8000 slash API user and let's put this into a variable let's say we'll use the structuring to grab the data let's also have a const user which is a ref and then set user dot value equals to data and let's display it here so if this works the user will be populated with whatever data laravel gives us let's import access another thing we need to make sure is that access sends the credentials the cookies with the requests and we can configure that by saying axis defaults with credentials equals true let's go in our browser and test this out here is our form I'll say test at example.com and password click login and here's our user details so that worked to end this video I'll answer a couple of questions I received via email Twitter and YouTube comments the first question is do I need to call the sanctum csrf cookie endpoint every time I make an authenticated request the answer is no you only do that for any unauthenticated request that isn't a get for example post requests to slash login slash register slash forgot password and so on why is the login route inside the web.php file and can I move it with the API routes you should be able to move it but I wouldn't at some point I might need to add token based authentication for mobile clients and it would make sense for slash API slash login to return a token and slash login to update the session cookie so I'd keep login inside the web routes file how do I refresh the csrf token the answer is you don't the csrf token is refreshed and prolonged every time a request is made it will only expire due to user in activity usually after 2 hours you can configure the session lifetime in your dot EnV file by updating the session lifetime key what are pre-flight requests a prefight request is the browser's way of asking the server if it will accept a specific cross origin request imagine a conversation going something like this the browser comes and says hey um can I make a post request from this origin to this endpoint of yours using these headers then the server says let me look you up and oh yes this origin is on the allowed Origins list and we accept post request so yeah go ahead send it over then the browser sends the actual cross origin request and that's all it is to it and that was it if you enjoyed this video don't forget to like it share it subscribe click the Bell button all that good stuff bye
Info
Channel: cdruc
Views: 50,647
Rating: undefined out of 5
Keywords: laravel, laravel sanctum, laravel spa authentication, spa auth
Id: 2zKoS8GsKK8
Channel Id: undefined
Length: 16min 55sec (1015 seconds)
Published: Sat Sep 17 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.