Next.js 14 Authentication (Kinde Auth, Server Actions, Roles & Permissions)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so you need to implement authentication in nextjs now nextjs is a full stack framework so you're going to have to protect the server side as well as the client side and that's exactly what I'm going to show you in this video I have even created an example project which showcases all of the things that you need to protect in nextjs so for example on the server we have server components these days and those are actually the pages so if you want to have a protected route in nextjs so for example if I go to dashboard here this is a private route here only logged in users should be able to see this so if I go here now I should be redirected to the login page because I'm not logged in and indeed I'm redirected here right so those pages are actually just server components in nextjs right so here in the app rouder you can see I have a folder here for dashboard and then I I have a page. TSX file right so that's for the slash dashboard route and then here you have your component that will match that route so it's just a server component and to protected page I'm using this kind server session function we'll talk all about that I'm using a service called kind o and it will give me the authentication status of the user and I can check if the user is logged in and if that's not true like what we just saw I will be redirected to the login page right so that's a server component but there are other things as well like client components for example here in this app we have the sidebar and this is actually a client component and when I log in let me quickly log in here so I'm going to click on log in I'm going to continue with Google and now I'm logged in and you can see that the sidebar here has changed the sidebar is a client component and it's now showing me the user information so in client component we also need to get access to the user information so those are the components but we also have server actions these days these are similar to your API end points in the past so for example here in this example app I can go to the dashboard route and what the user can actually do here is ask a question right so this example app allows users to Simply log in and ask a question for free so they can do that here on the dashboard route and here they can ask a question right let's say let's say how do I prevent MacBook from sleeping right now here when I submit a question this will actually be stored in a database and it's actually a server action that takes care of that and you can see it automatic and it immediately shows it here as well right but that's a server action and not everybody should be able to just submit a question only logged in users right only a question coming from an actual logged in user should be saved in a database not from anybody so you also need to check for authentication in the server action and it's actually going to be very similar to the route handlers or API route handlers but typically you want to use server actions these days these are meant as sort of a replacement for your API routes and nextjs we also have middleware this can be helpful because if you're going to make requests to a server component or server action or a route Handler before it touches anything on the server you can already run some logic in middleware and so that may be the place where you want to run your authentication logic now there's one more thing that you need to know which is that we also have something called authorization so here for example we also have an admin area page so if I try to go there right now you can see it do it doesn't work I'm getting redirected here to dashboard again because the user that I'm now logged in as is not an admin User it's a basic user but what I can do is I can go to this dashboard here and I can mark this user as an admin user instead of a basic user and I can save there and now you can see there's an additional link here in the sidebar I can click on there and here I can see the admin area so in the admin area we have the same component here that's showing all of the questions but here we only see the questions that were asked by this user that is logged in the admin can see all of the questions in the database right so here you have to deal with authorization so not only should the user be logged in there is an additional requirement that the user has the required permissions to be able to see this and to delete these questions right so we're going to talk about roles and permissions as well all right so right now we have the application without any authentication so here we have a dashboard page where I can just go to and I can even go to the admin area here and this is what it looks like in the code editor so here I have my app directory so in next JS you have a page. TSX file for each page right so here for/ dashboard we created a dashboard folder and then we have page. TSX now on the homepage I actually have these login and sign up uh buttons so if I go to the homepage here and these are just simple link components from nextjs and they are linking to SL login and slash sign up but I don't have Pages for those right so this won't work we're going to replace that soon all right so let's start off by protecting the dashboard and the admin area pages so I should not be able to go to dashboard here because I'm not logged in we don't even have a way of logging in so first of all let's actually remove it from the sidebar we should not even see this if we are not logged in so let's go to the sidebar here it's actually a component here and here in the sidebar I have this array with all of the routes right so this is the react way of doing it right so you have a an array of routes and then you map over that where you actually create a link for each of those routes so right now it's showing the dashboard and admin area routes because that's what we have in the here in the array however we don't want want to see this because we are not logged in so I'm going to comment this out and save here so now we don't see those links anymore so now it's gone from the sidebar but I can still go there directly so if I go to the address bar and just type in/ dashboard you can see I can still go to that page so how do we protect this page so now we're going to use kind o and they make it super easy to get started so they have this guide here I will just quickly go through it so I have already created an account and once you create an account they will immediately set up an application for you and they will ask you how you want your users to log in for example with what kind of social login I'm using Google here or maybe passwordless or maybe both I've already done that so this is my application here and I can get my details here all right so then we need to install here for an existing project I will just copy this this is going to be their mpm package that we need so I will quickly install this basic copy paste here all right so now that is installed all right so next Let's see we need to set call back URLs so here in the details here if we go down here um these are the Callback URLs that we want so after log out they should go here right so those are going to be the Callback URLs and then we need to copy paste some environment variables now in nextjs nextjs actually recommends that you use em. local however I'm using Prisma in this project and Prisma works withv out of the box and it's actually quite cumbersome to change that for Prisma so whenever I use Prisma I kind of default on using the EnV file for all of my environment variables so that's what I'm going to do here as well so here if I go down here I can copy all of these environment variables and I'm just going to paste all of them here so I need to get some of the information here I can get that from my application here let's see so I copied the information now this is a secret so you want to make sure that you're not showing this to anybody else you can see it in this video because I'm going to remove this after recording the video right so make sure that if you do it in EMV that you also include that file in yourg ignore right so I have included that here so then the final step here is to set up this kind of Route Handler so let's see that needs to be an app and then it's going to be API and then it's going to be o and then it's going to be square brackets kind o the second one is capitalized now here in the example they have route. Js so let's actually just follow the example so here then I can just copy this so that's all the setup that we need takes like 2 minutes and now we can protect that dashboard route so let's actually start there so now I'm going to my page. TSX file because that's what I'm using here when the user is going to for slash dashboard right and I can still go there I ref I can still go there but now of course here we want to check if the user is actually logged in so how do we do that so this is a server component and anywhere on the server you can use get kind server session so this works in server components as well as server actions as we'll see and what this will give you is a lot of things actually but what we want to know is if the user is authenticated and I need to import this all right so I need to import it from here and now I can use is authenticated now this is actually a function so here we need to call that function function so we can do await is authenticated and then here we know if the user is actually logged in or not so if the user is not logged in we don't want to continue rendering this component we want to redirect them to the login page see now here with redirect you want to make sure you use the next navigation and then here what we want to do is we want to redirect actually not to a slash login route because we don't have slash login here we don't have a login folder we actually want to send it to the route that kind is managing I want to send this to API o login so then kind can take care of all of the authentication stuff right so I'm just going to send all the traffic to kind there all right so now if we go to uh SL dasboard if I press enter here well what should happen is I'm not logged in so I should be redirected so if I press enter here let's see what happens and indeed I'm redirected to the login page so this is a page that's actually hosted by kind you can also customize this to be on your own domain and you can also customize the design of this login page however I think it looks perfectly fine so I will continue with it like this so here I have configured my app to to use the Google login or passwordless email so I'm going to use my Google account to log in here so let's see if we can then access the dashboard route and you can see when I log in with my Google account I am on the dashboard route so if you look back at the diagram again so here that was a server component right so dashboard is a server component so that's how you can protect a server component and now let's take a look at client components here as well because what I also want to show now is I'm logged in I also want to show a log out button let's do that in the sidebar and the sidebar is a client component so how do you get access to this authentication stuff on on the client let's go out of here and let's go to the sidebar here so the sidebar is a client component because I'm using this use path name hook so we can show some special styling for the active link and that's going to happen client side so in order to make that work we need to convert this into a client component and now what we want to do is in the sidebar we want to show some user information from the logged in user so how do we get access here to the to the logged in user information so here on the CL client you get the following function it's actually a hook use kind browser client so I'm importing that let's see I'm importing it like this and what do we get from here well we want to show a couple of things so we want to show the user information their profile image and also the email that they're logged in with we actually get that here as a user object we also simply get a Boolean here so is authenticated now we also get an is loading here so it may take some time before kind can give you that information so we can render something else uh while it's doing that all right so this is the information that I want and then let's say at the bottom of this sidebar I want to display that information so we're not going to type that out I will just paste what I have prepared for you so I'm just going to paste that right here all right so here what am I doing here let's see so here we have the div and in the div we're going to check if it's loading if it's loading I can actually show a loading spinner with just tnd CSS so while kind is getting that information I can show a loading un loading indicator all right so then here we can show a picture if the user has a picture set I'm going to use the image component from nextjs and let's see if the user does not have a picture we're just going to show a circle a colored circle with the first character of the user's name and if we can get the email we're going to show the user's email and at the bottom what we can also do is if the user is authenticated we can show a log out link um I actually can import that from kind as well well so let's see this is the log out link that you get from kind all right so let's actually see what we get if we do that now you can see I'm showing the user information here in the sidebar and I have this log out link as well now it's good to mention with nextjs when you use an image you need to specify the host name here in the next config file right so here for example when you're getting an image from their Google account it's actually some Google user content.com domain that you need to add here right so if you're using GitHub login for example you're using their image you need to add this uh host name but you will see that once you start adding an image it will cause an error and you will see which host name to add right now I'm logged in right now and we also want to show well the dashboard route right so here right now I commented this out but of course we do want to show that route so we do want to show it again so now if I comment this in again we can see the dashboard route as well right so now everything is protected as well as the UI is updated it's congruent with my authentication status so if I log out out let's see what happens if I click on log out I'm redirected here to the homepage but I can still see the dashboard link here because well I commented back in again so we can all we can always see it so here where we mapping over those routes we may want to check for something right so we may want to have something like requires off let's say that's true and so now here when you map over before you actually render this on the page we want to check so here we get path name but now also requires off if the route requires off and the user is not authenticated we don't want to render anything so if I save here now go back you can see this route is this link is gone as well right so now we've seen how you can get that information on the client as well as on the server so let's continue here so now I want to log back in again so we saw a log out button but now what about these login and sign up buttons If I click on login remember that was just some placeholder button that I have so on the homepage here I just have my own link component here linking to slash login but I don't have a login route here here so we got a log out button from kind but we also get a login and sign up button so here I can actually just write log in link and it will actually give me this Auto Import and I will make sure the closing tag is correct as well and then also register link so register Link Works the exact same now here I want to remove the HRA because kind of will manage the the routing for that behind the scenes I can keep the the Styles and the path for the import does need to be this it needs to be for/ components at the end and then I can remove this link from nextjs right so now these are the components that we get from kind so now I can log in again it will direct me to the login page here where I can then continue with Google again so let's do that so then it should log me in and indeed everything is working here and it also immediately redirects me to forward SL dashboard right so you can specify that here with post login redirect URL you can specify where the us where the user should go after logging in but you can also specify it in an environment variable that's actually what we've done here so so post login redirect URL is that for/ dasboard okay so this is what we have so far now what about that other route that admin area so here we don't see admin area in the sidebar which is good because this user let's say is just a basic User it's not an admin but what if I just type in admin area and just press enter you can see I can still go there so we haven't protected the admin area page yet if you look at our diagram here that page is also a server component right so we want to do the same as what we did for the dashboard so here if I go up a little bit so here for the dashboard we were doing this to protect this route I can copy this and I can go to my admin area pat. TSX and I can do the exact same so here before we continue rendering here we want to check if the user is even logged in and later we will check if the user is then an admin we'll talk about that in a second so here it's the same as before all right so I get an error because I'm not getting the import pads correct so here the import pads are important make sure you get the right ones all right so now I can still go to admin area of course because I we haven't checked whether the user is an admin but now we should not be able to go there when we're not logged in so if I log out here it will log me out so now if I try to go to admin area it should redirect me to the login page yeah okay so now those two routes the dashboard if I go there is protected as well as the admin area is protected now you may think it's a bit duplicative so here in the admin area page we're going going to do this check and then here in the dashboard we're going to do the check again so are we going to have to do this for every page well not necessarily if your whole app needs to be protected you don't have to do it in the page. TSX file you can actually just do it in the layout file right so you can also do this in the layout file now in this example that would make the whole uh app private right but here I want to have this homepage which actually should be public so here I don't want to do it in the layout here and you also want to be a little bit careful because using these functions will opt your route out of static rendering so it will make the route Dynamic and let me actually prove that to you if I run a quick build here of our app mpm run build it will give you some information at the end of the build so you can see here at the end that our uh homepage is still statically rendered right because our homepage isn't doing any authentication check it's not using cookies or headers so it can just be created once during the build and then just it can be served over and over again to any user I said that is statically rendered and that's what we want because that's that's best for performance however here for our admin area as well as the dashboard you can see now that they are Dynamic right and that's fine because this is user specific and so for user specific uh route we actually want Dynamic rendering um now if we would have done this in the layout file the homepage would also become a dynamically rendered route which would not be good for this example right so you do want to be bit careful where you actually make this check now what we may also want to do instead of doing it here in the page component we actually may also just want to do it in the middleware so if we go to the example again so here we are doing it directly in the server component so there is some request from client to server and then we're going to check it in the server component but what you can also do in nextjs is you can use middleware middleware will basically run before that right so the way you can see it is before it touches anything else on the server you can already run some middleware that will check if the user is authenticated and if the user is not authenticated you're just going to redirect them so you're not even going to start rendering any component before that authentication check has been successfully completed so technically it should be a little bit better in terms of performance so I quickly want to show you how to do that as well so you can create middleware actually in the root of your project here so actually if you're using the source directory it should be in the root of the source so that's a little bit surprising perhaps so it's not in the app directory right so here it's middleware dots and this would be a simple example with kind so kind allows you to do this with middleware as well so here you export a function called middleware you get the request right so here you you get that incoming request here in the middleware right that's what we get here and we're going to wrap that with the with OD function from kind now middleware you can specify on which routes it should run so we don't want to do this for the homepage because the homepage should be public right so only for dashboard and admin area do we want to check if the user is logged in right so here you can use the mature here maybe you want to do the middleware way but it's it basically works the exact same right so this is basically the exact same as what we're doing here in the middleware right but for this tutorial I will just continue with it like this because I want to show you the other things you can do with this function as well and even even if you're using middleware it's still possible for example that you're invoking a server action on a public route but that server action may need protection and we'll talk more about server actions in a second but middleware may not be enough in that case so you basically still need to do manual checks on the server sometime so I'm going to delete middleware for now uh but works the exact same so now next let's take a look at server actions this is going to be a big part of your app it's going to replace your API endpoints and typically you want to protect that of course so here for example I want to submit a question so if I say just testing if I click on submit question here let's actually see what happens so what are we doing here so here in the dashboard let's take a look so here we are doing that authentication check so here after that we are logged in then I'm getting all of the questions that were asked before from the database right and I'm passing that to the questions list that's what you see here these are all the questions in the database right now and then we have this form right so that's what I just filled out here that's the form so let's actually go there so here in the form we have have an action here so we have an action attribute and you can specify a function here a so-called server action and this is something that I put in an actions file here so let's see where did I put that I put that here in actually a separate folder and I called that actions. TS so these are functions that run only on the server right so these are server actions and I actually created one for adding a question right so here if I submit one this is going to add a question to the database and then I also have one for deleting a question right so we'll see that a bit later but for now you can see here when this function gets called which will happen when I submit the form right that's how server actions work I'm going to get the form data here and I'm going to add that to my database using Prisma okay and after that I'm doing a revalidation this will reender that dashboard page component that server component so that we can get the newly added question immediately here in the list as well so now if I click on submit question you can see it does inde did work and this is how it should work because I'm logged in but what if I log out is it possible for a logged out user to somehow invoke this function and it's actually a bit difficult to find out online how this works with server actions but it does seem to be the case and so it's possible that somebody who's not logged in can invoke this function so before we try to insert anything in our database we need to make sure that the user is logged in here right and just to show a little bit more about those server actions if I inspect here and see what happens in terms of the Network when I submit a question here so if I just say another test so if I click on submit question the server action will be invoked and you can see when that happens here we have server action we have dashboard here and then here in general we can see that there is a post request going out there's a post request on the dashboard route so with these server actions what you're doing is essentially creating a post end point at the same location as where you're in foking them so here this ask question form is on slash dashboard right now right so here that's why we now see a post request to slash dashboards so somebody could just invoke that somebody could do a post to slash dashboards maybe there are some identifier here yeah so here then with this identifier here in the payload they should be able to invoke our server action here so we need to make sure that here we actually should be uh authenticating the user and we can do it the same way actually so this function Works anywhere on the server so not just in server components also in server actions so what I'm going to do is I'm going to copy this and I'm going to paste this right here so get kind server session I need to import that and redirect as well from next navigation all of this works the exact same so I'm going to save here and let's see I made a mistake so I do need to import it from the right path here so make sure you get the path right so if I save here now it now should be protected so now if I go back here if I try again well it should work of course if I submit a question everything still works because I'm logged in right but now at least when I log out here I should not be able to invoke this function anywhere right so here we're doing our check manually again now what if you do middleware would the middleware also catch this well in this case it probably would although there is not that much information yet about server actions and protecting them but my guess is that they would however what if you invoke the same server action on a public route does the middleware also protect against that and my intuition is no so with these server actions you do want to make sure that you're doing it inside the server action before you do anything with your database you want to have your manual check there because you could invoke this on a public route and from my understanding the middleware would not catch that because you would not run the middleware authentication check on a public route all right so let's actually continue with that admin area so right now we don't see the admin area here in the sidebar because let's say I'm a basic user I'm not an admin so I shouldn't be able to go there however right now if I go to admin area just directly here with the URL I can still go there right so here this is obviously not what we want basic users should not be able to delete questions only admin users right so if we go to admin area here let's see we have admin area here's the page component we're just checking if the user is authenticated right so right now every logged in user well they pass this test so they continue here so what are we doing on this page we are again getting all of the questions from the database and then we're passing that to the same component questions list component however this time we pass the prop show delete button which shows this delete button how do we protect this even more so that only admin users can access this page so now we get into the realm of authorization so here we're going to work with roles and permissions I'll give you a quick example here so it's super easy to do this with kind imagine you had to do this yourself at next o it's just a major hassle also other things like teams and organizations it's also built into a kind here so here what you can do in kind is you have roles and permissions now kind recommends that you work with permissions and you can group together permissions into a role so let's start with a permission here so we can have a permission for example for asking questions so what I can do here is I want to create a permission here uh let's call it ask question allows user to ask a question here for the key this is what we will work with in our code they give us an example this ask and then colon and then the question so I will save that so this is going to be a permission that every basic user will have right and now we're going to create another permission for deleting questions all right so now that's added now I'm going to add another permission here so this will be delete question allows user to delete a question and here we can say delete colon question all right so I'm going to save here all right so now I have these two permissions and now I can group them together into a rle right so an admin user should be able to do both ask questions but then also delete questions right so now with roles you're going to group them together so I'm going to add a ro here let's start off with a basic user so I'm going to say this one is basic user user with basic permissions all right and as a key I will call that basic user and you can also assign this to any new user that signs up you can automatically assign this role which is very helpful all right so then which permissions should we add to this role so we have created two so far and a basic user should only be able to ask a question not delete questions so I'm going to save here and this is what every user will get now when they sign up right so they get this permission okay so that's a basic user now we're going to create an admin user let's say user with all permissions so I will say admin-user now make sure you don't assign this to every new user okay so then for the permissions well an admin of course should also be able to ask questions but then also they need to be able to delete questions so they get both of these permissions okay so I'm going to save here let's see all right so now we have these two roles and we have those permissions right and then what I can do is I can use the r here to assign that basic role actually to this user let's actually quickly do that so here let's go to my user I can see all of my users here in this nice dashboard as well so actually this is this one and I can go to roles and here I can assign roles to this person right so here let's say I'm a basic user and I already created this account before setting up roles but if this was a new account now this would automatically be become a basic user okay so I changed the role here now to make that take effect I do need to log out and log back in again because this is using Json web tokens under the hoot and uh that means that if you change something on the back end that is not immediately reflected here on the front end that's not just a kind o issue that's any solution with Json web tokens all right so here I'm back now and this is now a basic user so I should not be able to go to admin area however right now if I go there I can still go there so so here we don't just want to check if the user is logged in we also want to get the permissions of this user so here we get another function called get permissions and it should actually be singular so get permission and so just like is authenticated it's a function and we can do it here or we can do it here so here we can call that function right get permission and here we need to pass the necessary or the required permission so we called that delete colon question right so we're going to check if the user has this permission and this function will give us the result of that so has let's say required permission right so the result of this is what we're going to pass here and then it's a field on that called is granted so if required permission that is granted and if that's not granted so if the user does not have that permission what do we want to do here well here we don't want to redirect to the login uh page right because the user is already logged in it's just that they don't have the required permission so here we may just want to redirect him back to the dashboard let's say all right typescript issue is possibly null okay all right so now I'm going to save here and now let's see let's see if I can let me refresh here for clean slate now let's see if I can still go to admin area so now if I press enter here let's see what happens and you can see I can't go there I immediately get redirected here to dashboard right so it's hard to see here because it's so fast but I cannot go there so how no matter how many times I try I just get rid of directed to dashboard so now this page here is properly protected so that only users that have that permission of deleting questions can go there so now let's actually do give myself that permission and you do that with roles right so here now we're going to change this from a basic user to an admin user so I'm going to save here and admin user has that delete question permission and in a real world app you may have dozens of permissions right so you you group them together into a role so it's easy to assign a lot of those permissions to different sets of users this will not immediately take effect here on the client so the user would have to log in back again so here I'm going to log out and then log back in again all right so now I'm logged in again and now I'm an admin user so I should I should have that permission so now if I go to admin area I can go to admin area right so here this required permission it was granted so here the component continued rendering and uh returned the output now we also want to see it here in the in the sidebar so let's make sure that on the Cent In in the UI that the UI is congruent with our authentication and authorization uh flow here so let's go to sidebar here so here now we do want to add this uh route back right because we do want to see that so if I save here we now see our admin area route let me make this a little bit smaller this right so now we have all of the routes now this means it would always show this so if I log out now if I log out let's see we still see admin area here here right so here we were doing something like requires off to make sure that only logged in users are going to see that right so we could do the same if you do this I'm logged out now so I don't see it right but now if I log in again let's quickly do that continue with Google all right so now I'm logged in and indeed I see all of these routes okay so because now it's requires OD so logged in users will now see both of them however we don't want to see this one if I'm a basic user right so this one should not only have this Authentication this logged in check essentially but this one should have another check here to see if the user has the required permissions I'm going to make myself a basic user again so let's go quickly do that here I'm going to make myself a basic user okay and then I'm going to quickly log out and log in again all right so now I'm logged in again and I'm a basic user so if I not if I not go to admin area you can see it immediately redirects me to dashboard now here of course in the UI we want to make that congruent with the logic here as well so we should not be able to see this link because we're a basic user we should not see this admin area links how can we do that here so we only want to see that link if the user has that permission of deleting questions let's say so one thing we could do is instead of having this requires o we could be more specific we could say something like required permissions to enter that page or route and so here for these two we can say these are the required permissions so if you want to go to the dashboard well what can we do on the dashboard well we can ask a question so anybody that goes there needs needs to have this permission and here what can you do in the admin area well here you can delete questions so anybody that goes there should have these permissions so we only want to render these two if the user has these permissions right so here we need to know the user permissions as well so previously we saw it on the server side now this is on the client side again this is a client component right so how do you get the permission here well here it's get permissions plural so get permissions and here I can just call that it's not asynchronous and here I can extract all of the permissions from this user so just like that so this will give me all of the permissions that the user has so what we need to do is before we actually render one of these links we we need to check if the user permissions conform to the required permission so let's see we can remove this now this was what we had before now we have required permission so these are this is an array with all of the permissions that are required to enter that route so let's see if if GitHub co-pilot can help me out here all right so GitHub co-pilot unfortunately doesn't seem to help me out here so we want to return this Li with this link when well let's see when it's a public route for sure right so when there is a public route so let's see a public route doesn't even have required permissions so if there if if there are no required permissions right so if there are no required permissions then we will we will gladly return this right so let me add a set of kly braces here right so now if there are no required permissions we will return that or there are required permissions um but the user has them right so um we need to check for each of those required permissions it's an array so we can go over each one in that array and all of them right so there's an every method on an array so we go over each uh permission let's call it P we're going to check for all of them if they are in this permissions right so here we can check permissions that's what we get from kind and we can check if it includes that permission that we're going That We're looping over here okay let's see if I made a mistake all so so permissions initially may be undefined so I'm going to do optional chaining there all right so what we do now is we check if the user has all of the permissions in this array before we render that here in the UI so now you can see I'm a basic user and indeed we see dashboard here but not admin are because that is indeed off limits for us we're just a basic user now one last time I'm quickly going to make myself an admin user and not a basic user all right so successfully updated so let's quickly log out and log in again so now I'm an admin so I should see the admin Link in the sidebar as well and indeed I see the admin area link here as well so that is a very simple example of working with roles and permissions both on the server side as well as on the client side all right now very quickly uh we also want to be able to delete questions here that's also a server right so here I have that delete button here let's see I have on click I'm invoking a server action here delete question I'm passing the ID right so let's go there so that's the other server action that I had here and just like the other one this is also what you want to protect so we can actually do the same check as what we just did for the admin area uh page component and so here what we were doing is checking login status but then also if the user has that permission and since this is also all running on the server all of this works the same because this is a server action right so here before you do anything with your database you want to make sure that all of this has been passed and this is a bunch of boil plate code and it would be kind of ugly to repeat this for every server action you can make all of this much cleaner by creating some utility functions or maybe even have some kind of higher order uh server action that wraps all of them and adds this check right so there are some cleaner ways of organizing all of this but this is how you would protect your your actions here so now I'm an admin user let's see if I can still delete questions yeah I can right so I'm an admin user and I'm an admin user so I should also be able to add questions and indeed I can do that all right so last thing I want to show you here is we have this list of questions these are all the questions in the database but it would be nice if we could just show the questions that were asked by the user that is logged in so if I go to my uh dashboard page right so here with Prisma I'm just getting all of them from the database so all the questions in here and empty here means get all of them now in the real world we may want to be a little bit more specific so we only want to get the questions only the questions that were asked by the user that is logged in but how do you work with that because we're using a third party service here and the third party service has all of our user data well you can export your user data of course you can export that but you also can use the ID of the third party service so here what you can do is you can change your schema a little bit so here in schema the Prisma whenever you insert a question you may also want to attach the ID of the kind user object so here I can say kind of ID and that's going to be a string now here with Prisma you need to regenerate the Prisma client okay so now what we want to do is here when we get the questions we want to make sure that we only get the questions of the user that is logged in so here we can now use the kind of ID so how do we get that ID so we get another function here called get user so here we can get the user information right await get user and now we can just use user. ID right this is the ID of the user object that will all be managed by kind right so we don't have to worry about managing and storing all of the user data that's what the third party service that's what kind o is doing in this case but of course we still need to work with that user object so this is one example of doing it so whenever you submit a question here whenever we add a question here we're going to also add the ID of the user that submitt that submitted that question so we want to do that in the server actions here as well so here when we add a question let's go to the server action here now here we also want to add the kind o ID and this will come from this get user right so it's all the same here it's all on the server so get user we can get the user I will just cheat a little bit here so now when we insert a question into the database we're also going to attach this kind of ID so then next time when you fetch the data from the from the database you can do it for only the user that is logged in right so now let's see if all this still works test and I get an issue here because I need to update my database here so I'm just going to reset everything so yes all right so I just reset my database so now I can still add a question as you can see test two test test three right so now when I go here and go back again I will see all of the questions that I asked now these are these are the only three in my database right now but what if I now log in with some other user if I log out here I should not see those questions let's actually log in with some other account that I have another Google account my support uh email so now I'm in the dashboard again but you can see I don't see those three questions because those weren't asked by this account it was some other account that asked them right so now I can still do all of this but now I can uh personalize this a little bit better right so this is a quick example of sort of synchronizing an external third-party authentication surface with your own database so that was a lot to take in we talked about a lot of Concepts I want to thank kind for sponsoring this video check out the website and then I hope that you learned a lot this was an interesting project I think and with the new nextjs there's a lot to think about we have client side server side but as long as you keep this diagram in your mind I think it all becomes a little bit easier to understand so thanks for watching this video and I hope to see you the next one bye
Info
Channel: ByteGrad
Views: 13,297
Rating: undefined out of 5
Keywords:
Id: Z-v6MxJGPS4
Channel Id: undefined
Length: 40min 18sec (2418 seconds)
Published: Thu Dec 07 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.