Laravel Sanctum SPA Tutorial - React SPA Authentication With Sanctum

Поделиться
HTML-код
  • Опубликовано: 26 июн 2024
  • Authenticate your SPA with Laravel Sanctum where SPA & Laravel API are on two different repositories. In this video, you will learn how to authenticate your NextJS SPA, how to protect the dashboard from unauthorized access & how to configure cors for Laravel correctly.
    🤝 You can support me by giving my videos a 👍 & by subscribing to the channel ✔️
    -- Next.JS SPA Front-End Source Code --
    github.com/ggelashvili/nextjs...
    -- Laravel Sanctum API Back-End Source Code --
    github.com/ggelashvili/nextjs...
    -- Note --
    This works for Laravel versions 7.x & up. If you are trying to do this on earlier versions then make sure to pull in the github.com/fruitcake/laravel-... package, this is included in Laravel's core since 7.x.
    Also at 3:23, my SESSION_DRIVER is set to cookie. This is not important and it is up to you what session driver you want to use. There were a lot of devs who had issues authenticating their SPAs that were on different ports locally and changing file to cookie was the solution. I had the same issue which is why I have it set to 'cookie'. So if you are having such issues you can try setting driver to the cookie & see if that helps. Note that having SESSION_DRIVER set to a cookie will expose encrypted session to the browser. In production, I recommend using Redis as the session driver which is what I use on my apps.
    -- Table of Contents --
    00:00 - Intro
    00:42 - Install Laravel Sanctum
    02:23 - CORS/Session Configuration
    04:57 - CSRF Protection
    08:02 - Client-Side Login (Keeping User Logged In Using Custom Cookie)
    08:50 - Protection Against User Manually Creating Cookie (Axios Interceptors)
    10:42 - Server Side Redirect To Prevent Flashing Of Unauthorized Page

Комментарии • 95

  • @RiiPlay69
    @RiiPlay69 Год назад +2

    Hey! I was looking for this kind of thing for so long, thank you for sharing this, most helpful tutorial I found about the topic (especially the handling on the client-side) !

  • @prasoojas2093
    @prasoojas2093 Год назад

    Thanks for the quality tutorials❤

  • @dibbyo456
    @dibbyo456 2 года назад

    Exactly what I was looking, I will try implement this on my new vuejs project.

  • @alaskim3956
    @alaskim3956 2 года назад

    best video and explanation ever love u bro you made my day easy 💖💖💖

  • @7Janiel
    @7Janiel 2 года назад +1

    use 'then' for success response and 'catch' for error
    example:
    apiCallFunction(params)
    .then(data => {
    console.log('Success:', data);
    })
    .catch((error) => {
    console.error('Error:', error);
    });
    Good tutorial

    • @ProgramWithGio
      @ProgramWithGio  2 года назад

      Thank you. I did use .then(), agree about catch though 👍

  • @memack101
    @memack101 2 года назад

    Thank you.

  • @M7mdCC
    @M7mdCC 2 года назад

    Awesome tutorial 👍👍 Please make tutorial for nextjs Apollo client + laravel lighthouse graphql + sanctum

    • @ProgramWithGio
      @ProgramWithGio  2 года назад +1

      Thank you. GraphQL is in my list of things I want to make tutorials on, so hopefully I get to it soon 🤞

    • @M7mdCC
      @M7mdCC 2 года назад +2

      @@ProgramWithGio Also if you have time to continue this with some videos series' like fetching data with SWR , pagination !
      Thanks
      🙏

  • @thedavistheory7674
    @thedavistheory7674 4 месяца назад

    Guys btw, there was a breaking change a few months ago and so if you are using the latest version of axios, you should include the
    withXSRFToken: true
    property as well

  • @beberosak
    @beberosak 3 года назад

    Hi, great video!... At 10:00 I was wondering if wouldn't be better to just throw error instead of rejecting it?, otherwise you won't be able to tap into 422 validation messages.

    • @ProgramWithGio
      @ProgramWithGio  3 года назад +2

      Thank you. Sure you could do it that way, there are multiple ways of doing it. I think in other videos where I add Laravel Fortify I change this to catch 422 as well github.com/ggelashvili/laravel-fortify-spa-frontend/blob/main/src/util/api.js

  • @yeongjong9395
    @yeongjong9395 3 года назад +2

    Hello! Thanks for the great tutorial!! I'm wondering, is there an alternative approach to getInitialProps in the higher-order component (withAuth) as I am using ReactJS (scaffolded from Laravel). Thanks.

    • @ProgramWithGio
      @ProgramWithGio  3 года назад +2

      You're welcome. Is your SPA (react) on same repository as Laravel? I assume it is since you mentioned it's scaffolded from Laravel. There are few ways you could achieve about the same. One is to simply store isLoggedIn flag in meta tag on your app.blade.php and access it from your react app and store in context and use that to check if user is logged in it not.

    • @yeongjong9395
      @yeongjong9395 3 года назад

      @@ProgramWithGio Thanks for the quick response. Yes. Is in the same folder. Will try that. Thanks 😊 what if in future I would have to separate into two different folder, is there anyway way to do that? Thanks.

    • @ProgramWithGio
      @ProgramWithGio  3 года назад +2

      ​ @Yeong Jong You could also do the same thing I did in this video without getInitialProps, its just getInitialProps allows you to check things on the server before rendering anything on the client-side, avoiding that bit of a flash of the dashboard page if the user is not logged in (10:42), but in most cases that is ok though. So you could simply store isLoggedIn in a cookie the same way when the user logs in & store it in context. It would still work.

    • @yeongjong9395
      @yeongjong9395 3 года назад +1

      @@ProgramWithGio thanks for the suggestion. Will definitely try it. Yeah. I noticed that getInitialProps is part of NextJS, which is not available in ReactJS

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      @@yeongjong9395 You're welcome. Good luck

  • @Dushan1999
    @Dushan1999 2 года назад

    Nice video man! Can you please tell me one example of your login credentials, since all seeded data is encrypted and i can't login to see the dashboard?

    • @ProgramWithGio
      @ProgramWithGio  2 года назад

      Thank you. Just make a user through tinker either using factory or manually creating a new user model & saving it. If you are using my code you would have no users by default, you need to create it.

  • @jooeeee
    @jooeeee 3 года назад +1

    Thank you for your video ! I haven't seen all the video but i will. We have React Front-end App and Laravel Back-end App, and we are wonder how to manage user's session. Maybe Sanctum can do the job, i have trying Passport but i wonder if it's the best choice.

    • @ProgramWithGio
      @ProgramWithGio  3 года назад +1

      If both react and API are on same domain you can use Sanctum sessions. I personally prefer Sanctum. Unless you need oAuth features I would go with Sanctum instead of Passport.

    • @jooeeee
      @jooeeee 3 года назад +1

      @@ProgramWithGio Thanks a lot for your advices :)

    • @jooeeee
      @jooeeee 3 года назад

      @@ProgramWithGio I have a Webservice between React App and Laravel, is this configuration can work with sanctum ? When i log in, i have no CRSF cookie. I have put into the .env of API Laravel : SANCTUM_STATEFUL_DOMAINS=localhost:8688 (which is correspond to the webservice).

    • @ProgramWithGio
      @ProgramWithGio  3 года назад +1

      @@jooeeee SANCTUM_STATEFUL_DOMAINS should be your SPA domain, what is the purpose of the Webservice that runs between SPA & API?

    • @jooeeee
      @jooeeee 3 года назад

      @@ProgramWithGio Okay, i will try to set this. Bidirectional interactions between SPA and API.

  • @madtin
    @madtin 3 года назад

    Hello! Im having trouble having my nextjs app in localhost:3000 and my laravel app in a vhost locally which is something like laravelapp.test Is it possible to set the cookie having this setup?

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      Don't think so because it's not same top level domain. You can have Laravel app on different port on localhost and then it will work, or you have to make your nextjs app be subdomain something like spa.laravelapp.test, though I have not tried such setup

  • @MohdRusmanAriefARahman
    @MohdRusmanAriefARahman 3 года назад

    Why do we need to add login and logout tu cors.php? Is that referring to the POST login and POST logout? We are not using the GET request for both login and logout right?

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      Because in this video login & logout routes are within web.php file and not within api.php so had to allow them. In Laravel Fortify series I move those routes to api.php & remove them from cors.php. I mentioned in the video that you don't need to do that if your login/logout routes are within api.php then you would make post request to /api/login & /api/logout. In my case for this video I make post requests to /login & /logout (04:34)

  • @permanar_
    @permanar_ 2 года назад +1

    Hello.
    I'm kinda new to backend stuff so, how do we do if we want to it works also on different domains?
    You previously mentioned that this (sanctum) only work within the same domain right?
    Then is there any alternative? Should I go with Passport?

    • @ProgramWithGio
      @ProgramWithGio  2 года назад

      Hello. You could use sanctum for that but instead of session based auth you would use token based auth. Sanctum has that ability, when request is coming from a diff domain it will try to authenticate using the bearer token.

    • @permanar_
      @permanar_ 2 года назад

      @@ProgramWithGio hey, thanks for the kind reply man. Ok, I got it. But anyway, then what's the difference between Sanctum and Passport?

    • @ProgramWithGio
      @ProgramWithGio  2 года назад

      No problem. I have a video on that, check it out: ruclips.net/video/mdyoNwfIS80/видео.html

  • @majlosko94
    @majlosko94 3 года назад

    I think isLoggedIn condition is not secure, because if you use hoc withAuth on the page without any API request and you manually set cookie to true, you can get to the protected page on the FE, am I wrong?

    • @ProgramWithGio
      @ProgramWithGio  3 года назад +1

      I explain that scenario in the video (8:44). You won't get any useful information or action if you manually set that to true. The moment it hits API you will be auto-logged out on the frontend and redirected to the Login page.

  • @user-us2bj1it4c
    @user-us2bj1it4c 3 года назад

    in which folder is the admin panel created? in client project or inside laravel project?

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      It depends. I would put admin panel separately from the client unless the end users are able to log in also. So it depends what sort of admin panel you have.

  • @_ulghun
    @_ulghun 3 года назад

    hello, thank you for very helpful tutorial ✨
    in the video 8:17 you didn't explain how do you store cookie to the server,
    and what happen if I login success and then remove ticket_managment cookie from browser , goto then '/login' page and login second time ?
    I tried my self this process and I got cors error, can you help me resolve this problem?

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      Cookies are handled by Laravel so not sure what the question is. 8:44 I explain what happens if you manually create the cookie.
      Do you mean the cookies stored from nextjs? It simply creates and stores cookies the same way you would do it in PHP.
      You might need to add the handling for the case where you manually remove the logged in cookie and then visit /login page. Though I'm not getting cors errors, can you share the .env file?

  • @jahadempire7934
    @jahadempire7934 3 года назад

    Can you include the logged-in user details in NextJS? where you will store it on Redux? Nuxt has auth-module where we can just access the user details of logged-in user.

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      I don't use Redux but you can store them using context. You could make a get request to fetch user details and store necessary info in context.

    • @jahadempire7934
      @jahadempire7934 3 года назад

      @@ProgramWithGio hi, may I know your opinion why you don't use redux?

    • @ProgramWithGio
      @ProgramWithGio  3 года назад +1

      @@jahadempire7934 I don't have a use for it. For my needs context hooks are more than enough. I'm sure Redux has its use cases but I don't like to overcomplicate codebase when it's not needed

  • @ITONEMM
    @ITONEMM 2 года назад

    Is it working with different domain if frontend with proxy request feature?

    • @ProgramWithGio
      @ProgramWithGio  Год назад

      Sorry for the super late reply, just came across this comment, RUclips did not notify me about it. I'm not exactly sure what you mean, if you still need help on this feel free to send me a DM on Twitter 💙

  • @gustavosantos1152
    @gustavosantos1152 2 года назад +1

    Hello! I'm facing some issues in auth part. I'm following the auth flow apparently right. I call the endpoit to set CSRF cookie then I call the endpoint to login, and it returns 200 code, but when I try to reach some protected endpoint it returns 401 Unauthorized. I checked the cookies and all are being sent correctly. Could you help me? Thanks

    • @ProgramWithGio
      @ProgramWithGio  2 года назад

      Hello. What is your session driver set to in env and session domain? You can DM me on twitter and I can help you troubleshoot this issue

    • @JoshuaTHawkins
      @JoshuaTHawkins 2 года назад

      @@ProgramWithGio Did you ever solve Gustavo's problem? I'm encountering the exact same issue.

    • @ProgramWithGio
      @ProgramWithGio  2 года назад +1

      @@JoshuaTHawkins yes, I think he had a typo in his env variable, SANCTUM_STATEFUL_DOMAIN missing S in the end, should be SANCTUM_STATEFUL_DOMAINS
      Check if it's the same issue.

    • @JoshuaTHawkins
      @JoshuaTHawkins 2 года назад +1

      @@ProgramWithGio It actually was a different issue. But I managed to solve it. Thanks again for your great tutorial!

    • @william.darrigo
      @william.darrigo 2 года назад

      @@JoshuaTHawkins hey Josh. i'm having the same error. Could you please tell what you did to solve this? Thank you

  • @sazalahamed1443
    @sazalahamed1443 3 года назад +1

    hello, your laravel project & react project is different and independent. But I installed reactjs inside laravel project. that means URL+PORT is same for me. so what changes is needed there for .env... please give me an answer for it... I loved your style ## I didn't use NextJS

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      Thank you. Are you building SPA? I don't think you need much changes in .env because domain is same. If it's not SPA you probably don't even need Sanctum

    • @sazalahamed1443
      @sazalahamed1443 3 года назад

      ​@@ProgramWithGio Yeah, I am creating SPA with laravel backend rest api. this is my ReactJS directory "resources/js/...." inside laravel. please give me guide.
      github.com/DevSazal/reactjs-tweets-crud-app-by-laravel-v8-restapi/blob/master/resources/js/pages/Main.js
      ## I didn't use NextJS

    • @ProgramWithGio
      @ProgramWithGio  3 года назад +1

      ​@@sazalahamed1443 By the looks of it I don't think you need to make same changes as I did with nextjs to your .env because you have your SPA on the same repo, the CSRF token is initialized for you & saved in meta field. In my case nextjs app was in separate repository & on subdomain, for those cases I needed to use Sanctum. You technically don't even need Sanctum to be honest, regular session based auth should work. Have you tried without Sanctum?

    • @sazalahamed1443
      @sazalahamed1443 3 года назад

      @@ProgramWithGio hey brother, I did try without sanctum firstly, but that time it will not work correctly. Then I used sanctum middleware way with api route file, and it works for protecting API routes. that's api crud operation worked only when user logged.
      {1st problem} by after successfully logging redirect not work. It tried "react-router-dom" let history = useHistory(); history.push("/home"); but above code not worked and says "Invalid Hook Call Warning".
      {2ND} withAuth(Main) is not preventing "Main" component by url from non-logged user. means operation isn't acceptable as he is still non-logged user by laravel backend.
      ** your case, you used redirect with next-router.

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      @@sazalahamed1443 In order to prevent user from accessing protected page you need to store "isLoggedIn" flag somewhere in React, either a cookie or context, in your case you can just use context, & then check in your router or higher order component if user is logged in or not, if user is not logged in & the page requires user to be logged in redirect user to login page.
      The issue sounds like it has something to do with React & not with Laravel, so I would look into some React tutorials, you basically just need to keep the "isLoggedIn" flag on front-end to control when & where to redirect user

  • @ironsand
    @ironsand 2 года назад

    If I set the constant SESSION_DOMAIN=localhost
    in my .env file, the request to '/sanctum/csrf-cookie' simply won't set the cookie anymore -- it does absolutely nothing. When I remove the .env constant, it sets the cookies again. Does anyone understand why is this happening?

    • @ProgramWithGio
      @ProgramWithGio  Год назад

      Sorry for the super late reply, I just saw this comment, I did not get notified when you added a comment so it was kind of lost in the limbo. If you are still having an issue with this & have not figured it out ping me on Twitter & I can help troubleshoot it 👍

  • @eleazarfederio1718
    @eleazarfederio1718 3 года назад

    what if i see the XSRF-TOKEN & laravel_session in the response header but it doesn't save in the browser cookie?

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      Most likely a misconfiguration. What's your SESSION_DRIVER, SESSION_DOMAIN & SANCTUM_STATEFUL_DOMAINS set to in .env?

    • @eleazarfederio1718
      @eleazarfederio1718 3 года назад

      @@ProgramWithGio my SESSION_DRIVER, SESSION_DOMAIN & SANCTUM_STATEFUL_DOMAINS are all set to 127.0.0.1

    • @ProgramWithGio
      @ProgramWithGio  3 года назад +1

      @@eleazarfederio1718 That is not correct, SESSION_DRIVER has to be file, cookie, redis, etc, check for available options, for now, set it to file so you can get it working. SESSION_DOMAIN should be localhost & SANCTUM_STATEFUL_DOMAINS should be your SPA domain whatever port that is on so if your SPA is on port 3000 then this would be set to localhost:3000

  • @leonardonoriega6563
    @leonardonoriega6563 3 года назад

    does this works on PWA? and how should we do this for an ract-native app for example?

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      You would use tokens for mobile app. Here is video on authenticating react native with Sanctum ruclips.net/video/ymLpLWklzxQ/видео.html

    • @leonardonoriega6563
      @leonardonoriega6563 3 года назад +1

      @@ProgramWithGio i realized bit before this comment but thanks!. amazing content you got here. was exactly what i need

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      @@leonardonoriega6563 thank you 🙌

  • @modaralkasem4027
    @modaralkasem4027 3 года назад

    The GET method is not supported for this route. Supported methods: POST..... why this error showed to me on login route ??

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      Which route? That error means that you are making GET request on a route that expects POST request. Same route with GET request doesn't exist.

    • @modaralkasem4027
      @modaralkasem4027 3 года назад

      @@ProgramWithGio
      no i make this post request:
      this.axiosInstance.post('/signIn' ,{
      email:this.state.sentUserName,
      password:this.state.sentPassword

      }
      and my route in laravel is :
      Route::post('/signIn' , [AuthController::class , 'signIn'])->name('signIn');

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      @@modaralkasem4027 Check in your JS if you are making another GET request to /signIn because that error simply means you are making a GET request where POST is expected. Are you sure the issue is related to /signIn route & not another route? If you share your code on github I can take a look, without code its hard to know what the issue is.

    • @modaralkasem4027
      @modaralkasem4027 3 года назад

      @@ProgramWithGio
      i think i select my problem which is xsrf cookie not saved and not showed on browser application tap so when make next request the response be ''csrf' token dismatch

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      @@modaralkasem4027 It's hard to see what the issue is without looking at the code. I would suggest you to try setting it up using my code first & then see what you are missing in your code.

  • @mariusguissou4282
    @mariusguissou4282 3 года назад

    The subject that you broached is very very interesting but we do not see anything practical on your screen. For your next videos remember to zoom in to make things more visible. If you can take this video by improving the image, that would make us happy. Thank you, you do a good job.

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      If you mean the font size & zooming in on the browser I agree that can & will be improved for future videos & have been improved in my PHP course's latest videos. This was one of the first videos that I've made, still new to creating content on youtube but improving step by step :). Thank you for the feedback 👍

  • @perfect.stealth
    @perfect.stealth 2 года назад

    Sometimes it logs in, sometimes it responds 429 Too Many Requests

    • @ProgramWithGio
      @ProgramWithGio  Год назад

      I'm sorry for the super late reply, I have not seen this comment until now, I did not get any notification about it. If you are still having an issue with this ping me on Twitter & I can help troubleshoot it 💙

  • @munandisichali605
    @munandisichali605 3 года назад

    Does this tech stack work on XAMP? I have a problem where it is not connecting to the server

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      Haven't tried it on XAMPP so not 100% sure. I would try Laravel sail with Docker, it's pretty simple to set it up

    • @munandisichali605
      @munandisichali605 3 года назад

      @@ProgramWithGio I think my problem is there, Lots of tutorials don't take into consideration US who are using xampp due to the cost of online developments, Thanks for your reply, I appreciate

    • @ProgramWithGio
      @ProgramWithGio  3 года назад

      @@munandisichali605 I take that into consideration and in my PHP course used XAMPP in the beginning as well. It's just not practical with Laravel which is why I don't use it. For everything else XAMPP is perfectly fine. You can also try Laradock. What error do you get?