Building an Authentication Flow with Next.js, TailwindCSS, & AWS Amplify - OAuth & Email + Password

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video i'm going to be building out a completely custom authentication flow in an xjs app using tailwind css and aws amplify now aws amplify implements authentication using a managed authentication service called amazon cognito now amazon cognito allows a few different types of authentication you can sign up with an email you can sign up with facebook or google and we're going to basically be combining a few of these together and then we're going to be actually writing out the completely custom authentication flow from scratch enabling users to sign up confirm sign up with sms or email sign in and then also maybe reset their password now this will basically be using a couple of different routes in an xjs app mainly just a main route and maybe a profile route we also may build out a protected client route and then we'll take a look at how to get the user's identity on the server using an api route or a server render route so i hope you learned a lot from this and we're going to go ahead and get started now so i'm going to go ahead and create a new next.js app using npx all right so after we've um created our our next js app we'll go ahead and install our dependencies now we know we're going to need aws amplify but we're also going to need the next js dependencies so to kind of learn how to do that they actually have some pretty good docs so we can just look for next js tailwind installation or something like that and then we should see this entire walkthrough so we just need to install these three dependencies from tailwind and then we're going to go ahead and initialize a couple of files that we're going to need for tailwind to run using npx so npx tailwind css init and this is going to create a tailwind config and a post css config next we're going to go ahead and install our css that we're going to need or kind of reference the css so we can now go into styles globals.css and add that so we'll go ahead and open up the project in our text editor and i'm just going to go ahead and remove whatever's there and add this and we're kind of ready to go there and i think that is about it so the next thing we're going to do is let's go ahead and get our amplify stuff going so i'm going to go ahead and initialize a new amplify project by running amplifying it i'm going to choose the source directory as the root directory and the distribution directory as dot next just choose um the default profile for me that's used one you can choose whatever profile that you're working with alright so once our amplify app has been initialized we can now go ahead and set up our app ids so the first thing i'll do is i'll visit console.developers.google.com and i'm going to go ahead and click on create new project and here i'll call this next js amplify auth and once this project is created we'll go ahead and set up our oauth credentials so we should now be able to go ahead and choose this new project from the drop down menu and we're going to click on credentials and the first thing that we're going to need to do is go ahead and configure the consent screen before we can enable oauth credentials and for the type i'm going to choose external and i will give this some basic information like next js amplify auth set a support email and set the developer contact email for me as well and then from here we should just be able to go ahead and click save and continue and then back to dashboard and then i'll go ahead and choose publish app to publish to production because we're going to be using in just a moment okay so the next thing that we're going to do is we're going to click on credentials and we're going to click create credentials and i'm going to choose oauth client id for the application type we'll choose web application and for the javascript origin i'm going to use localhost 3000 for now and from there we can go ahead and click create because this is going to give us our our client id and our client secret and then later we're going to go back and add our redirect urls or uris so now that we have that done for google we need to do that for facebook as well so i'm going to go to developers.facebook.com and click create app and i'll just choose something else as the type of app and for the app name i'll call this the same thing next js amplify off and from here we should be good to go so what i'm what i need now is to go to settings and basic and we should be given our app id and our app secret and we'll be needing this in the next step so now that we've done that we'll go back to the cli and we'll run amplify add auth and we'll choose default configuration with social provider i will choose email as the sign in type i don't want any advanced settings i will choose the default domain prefix and for the redirect sign in uri we can choose something like localhost 3000 and i might copy and paste that for the sign out uri as well for the providers we're going to choose facebook and google for the facebook app id go ahead and copy this and the app secret as well for the google client id i'm going to go ahead and copy this and the client secret as well and now we should be good to go so to deploy i can run amplify push and i'll just choose dash dash y and this will go ahead and just deploy without another prompt now while that's deploying we might want to go ahead and do some work on our client one of the things that we're going to need is a way to configure amplify so we can either call amplify.configure in the you know file itself or we can create like a global that we can end up using wherever we like and i think that's the way that i'm going to do this here so to do that i'll create a new file called configure amplify.js and here we're going to go ahead and import amplify from aws amplify we're going to import this configuration file called aws exports that's been created for us by the cli and then we'll call amplify.configure passing in the config and then wherever we want to use this we can just import it so one of the places we're going to need to use is in the pages directory in a file called profile.js that i'll go ahead and create here and this is where we're going to kind of do our sign-in functionality this is going to basically be our profile page what we might also want to do is go ahead and set up some navigation so i'm going to open underscoreapp.js and i'm going to go ahead and import link from nextlink and instead of just returning the component i'm going to return a div and here we're going to go ahead and set up some nav and here we're going to have a link whoops with an anchor and we'll do that a couple of times so for the first one we're going to be linking to the profile well actually let's make this one home and then this one profile and for the href we'll see use this as a like a backslash for the root and for the href here we can say slash profile and for here we're going to have a link to a protected page right now we're not going to be using this but after we um after we kind of enable users to sign in we want to show how to do client-side redirects if they're not signed in we want to have some protected pages so we have slash profile slash protected and slash at the roots now we might want to add some stylus here so we can use class name and set up some some tailwind class names so i might want to have like a padding y of maybe something like 4 and a padding x of like 12. i might want to have a border bottom of 1 pixel and that allows us to to do border b and we might want to say border gray to set the color to like a light gray border of 300 i also might want to set up some margin on my links so i might want to say class name is equal to margin left of eights or even maybe four it's a little bit better and then i'll put those put that on the second and third link okay so we have that set up let's go to our profile component now and let's go ahead and import use state and use effect from react because i know we're going to be needing those later we'll also import the auth class from aws amplify and then we'll create a component called profile and in profile we'll return a div and then here we'll be adding some stuff later and then we'll have a use effect hook and this use effect hook is going to be calling a method in just a moment now for the profile component we're going to be doing all of that authentication stuff here so when a user lands here we want to check to see if they're signed in and if they are we want to show their profile if they're not we want to automatically render a form for them to sign in using either their email address or sign up using their email address or to sign in using google or facebook so the first thing we might want to do is go ahead and enable that facebook and google in so to do that i can create a couple of buttons i can say sign in with google and then when the user clicks here we want to have an on click handler or we can say auth dot federated sign in and we can set the provider as either google or facebook in this case google and then we'll copy and paste this here and we'll set the provider here as facebook and we'll do that now once the user is signed in we will be redirected here and we can kind of get the user's information so we might have a function called check user that we'll invoke there and we can define it here where we can say auth dot current authenticated user and then we'll just log out the uh the user if there is a user so we're not using use state yet but we will in just a moment um so that we have this set up this is pretty good we can go ahead and test this out but the first thing before we do that once our backend resources have been deployed we need to now set up this redirect endpoint back into our app settings for google and facebook so i'm going to go ahead and copy this this is printed out here it's also given to you here in aws exports in the domain so either way you know you can you can just copy that and have it ready for for using in just a moment so now we're going to go to our credentials setup here we'll go ahead and choose the client in google and for the authorized redirect uris we're going to set that here so what i'm going to do is have the https slash with the domain and then i'm going to say slash oauth 2 idp response so the the full uri should look something like this so we have http actually this should be https and then the domain and then slash oauth 2 idp response and that's kind of what i have here so i'm going to go ahead and save that and i'm going to go to facebook and we need to do a few updates here we'll go ahead and set that redirect by going to products and we want to enable facebook login by clicking setup and then we can go to our settings here and we should be able to go ahead and set the valid uh redirects here and i'm using the https colon slash slash domain slash oauth 2 slash idp response but we also need to make a couple of more updates in our settings here so first of all we need to to have our app domain so i might have localhost 3000 zoom in a little bit there i will also go scroll down and set up a platform for web and then here our site url will also be set for localhost 3000 for now and then finally i need to set a privacy policy url as well as a terms of service now this is going to be just a domain that i have already set up but this could be whatever data domain you have it doesn't really have to you know be any certain domain for testing in my opinion i'm just going to be setting up amplifyauth.dev you could use whatever url you like this could even be living somewhere on github or something like that um so with that being said i should be able to go ahead and save this and then once it's saved we should be able to go ahead and switch this into deployment by saying we want it to be in development and for the category i'll just choose something like education okay so our you know oauth should be working now for facebook and for google so to test this out let's go ahead and go to our terminal and run npm run dev oh and there is one other thing since we've used the or we've created this configure amplifi configuration we actually need to use it here so i'll go ahead and import that here and save that and this should be all we need to kind of start using amplify so i'm going to go to localhost 3000 and we see that we now have our you know navigation going up here so i'm going to click on profile and this should load up our profile page and we can test out our authentication with google and facebook so we have a couple of very ugly buttons we'll fix that later but i'm going to go ahead and click sign in with google when we're now redirected we should be able to navigate to our profile and see that we have our information logged out to the console meaning that we are signed in so we see that we have all of the information about the user so the email you know other credentials and stuff there if we have the and if we go into the sign in user session and we see the id token and payload you have all of the other information about the user here including the sub which is kind of the unique identifier we also might want to give the user a way to sign out so to do that we can create a button here called sign out when they click this we can call auth.sign out and then now we navigate back to profile we should see that the user is not authenticated and then we'll also try signing in with facebook and we see that our social sign-in is working so now that we have social sign and working we can actually go ahead and maybe view these users in our cognito dashboard so we should be able to run something like amplify console auth and then we can choose user pool or you can choose both and just open user pool but user pool is kind of where we want to go and then if we click on users and groups we see that we have two users signed up i'm not going to really be going into the to the console much i just wanted to kind of show you that so now that we have that set up we go ahead and sign out and i think one of the first things that we might want to do is make our design look a little nicer now in our tailwind configuration that is located here i want to add a couple of updates because i want to extend the existing setup that tailwind gives us with two different i guess configurations the first is i want to set a spacing of 540 pixels this is going to be kind of where i set up my main form and i want it to be a set width so i'm going to set it at 540 pixels wide and then also i want to set a custom box shadow and the box shadow that i want to be set is for our form i want to kind of have a special box shadow and for a focused input i want to set a border on the input using the color that we're going to be working with which is i think pink 500 and pink 600 but there is no way to kind of do that directly with tailwind that i know of so i'm kind of setting this special box shadow for the input so now that we have that set up um we should be good to go and we can go ahead and start making some styling updates so the the next thing that i'm going to do is let's go ahead and open up our profile page and make a couple more updates so we're going to be needing to work with a couple of pieces of state so let's go ahead and create this and we're going to be using some ui state and the ui state is going to be toggling between different pieces of ui so we're going to be showing the sign up ui or the sign in ui that's going to be kind of set as a string in just a moment we're also going to be needing to set the form state and the form state is going to start off as an object and maybe we can create an object here called initial state and we can set the email address of the user we can set the the password and the auth code and the auth code is going to be stuff like their mfa code or if they reset their password and then for the form state we can kind of just set that as the initial state so we're going to be you know you using that in just a moment um the thing that's going to be updating the form state is an own chain channeler so we're going to have like a function on change it's going to be receiving an event and then here we can basically say set form state setting the event target name and the event target value and we'll be attaching that to our own our input on change handlers in just a moment but um what we need to start thinking about now is like when we're toggling between different pieces of ui state how are we going to be controlling that and there's a few different ways that you can do that but for me in react i can do something like this where i can say you know if the ui state is equal to sine n i want to show a sign-in form of some sort so the sign-in form that that we're going to be working with to start off is going to basically be you know this these buttons that we created a moment ago that i kind of copied to my clipboard but instead of just dropping them in there let's create a components folder that's going to hold all this stuff whoops close that i'll go ahead and create a folder the root of the projects called components and the first component i'm going to create is sign in dot js and this is going to return a div wrapping those buttons that we created just a moment ago so using that we can now just import that and basically show it whenever we we need to so to do that we'll go ahead and save that and we'll go over here and we'll import sign in and then we can say if the ui state is equal that we'll just show the sign in component and we can actually start passing in props so we can say on change is equal to on change because in just a moment we're going to be adding that on change handler and then we might even be needing to set the ui state because if they sign in manually we we want to wait to trigger that ui state a couple ways we could do that we could actually use hub which will listen to auth events and then it will change or we can manually change it you know after the user signs in so either way it works fine in this case we're just going to set it ourselves um the other ui state we might want to keep up with is signed in and if they're signed in we want to show um some type of actual profile so we might have like a div where we have some type of greeting where we're kind of using that profile information and for the profile information we might want to do something like giving the user a greeting and the way that we can do that is since we're already checking the user here we can go ahead and create some user statement and instead of just doing this we can instead do like a try catch block if the user is signed in we can say set user passing in the user now that we have that there we can now do some stuff here so what we might want to do is have like a paragraph that says something like welcome user.username and we might want to have a way for them to sign out so and then here we can call alt.sign out we can also call our setuistate method because the ui state needs to be set to sign in because that means they've already been signed out and i think that should be it maybe we would even want to set the user state back to null okay so that allows the user to sun um sun out so let's add some styling to this so what we might want to do is have um like some larger font here and for the text size we can say like text excel and we might also want to well that seems like to be probably a good you know a good basic style just to make the font a little larger and for the button let's add some styling as well so for the sign out button we're going to add we're going to set the text color as white full width a margin top of 10. we'll set the background color as this pink 600 color a padding of three and we want the button to be rounded okay so we might want to go ahead and test this out because we wrote a lot of code let's just see if this was working and it looks like it cannot import sign in because i'm importing it there instead of from the components let's try that again okay so nothing is rendering so let's go back and see what's going on here oh that's because the ui state is not set yet so um one of the things that we probably want to do is in this initial load we want to say set ui state to be signed in if this succeeds and then if it does not succeed we can say sign in there we go so we're still seeing um you know all this stuff we might want to go ahead and remove that sound out button because we don't need that in the sun and screen because apparently they should not be signed in yet if they're seeing this so let's try this again sign in with google we need to import auth here try that one more time all right so now if we get a profile we should see now that we're giving like a greeting welcome with our quote unquote username instead of using the user dot username let's use the user.email because that might make a little more sense and i think it might be in the user attributes so we might need to do something like user dot attributes dot email there we go that's a little better um it's still kind of ugly you know we have this full width going on and one of the things that we did a second ago was we kind of set up the um tailwind configuration to do our own tailwind configuration and what we want to do is set up some some styling using that um configuration which was basically that box shadow that was kind of the main thing so let me just close some of this stuff that we're not using and we'll go ahead actually and take a look at that tailwind config because we want to use the form box shadow we could call this you know main or something like that but it's essentially going to be like the main forum that we're going to be working with in our profile component at least and we're also going to be using this spacing so to set that up let's go back into our profile component and set some some stuff like around our main component so here we'll set a class name we'll add a few different classes here we want to set the background gray 50 which is kind of this very light gray and then we want a minimum height of the entire full height so we're just basically saying we want the minimum height to be the height of the screen and then we're also going to add a couple more divs to kind of or actually with just one more we're just going to wrap this in another div and then paste that back here and then we want to set some flex styling here we're basically saying we want to be flexbox with the column flex going up and down and we want to align the items in the center and then finally we actually want to add one more div here and instead of cutting and pasting all that i'm just going to do this and then here we want to set the width to be that 540 pixel width we want to set the max width as full and the margin top of 14. now we're using this responsive styling using the sm colon width 540 and we're doing that because when it goes below 540 i'm sorry when it when it becomes a small screen essentially i forgot the number of pixels we want it to become full width but if it becomes any larger than the small break size let's actually look at what the small break size is until when i'm kind of curious so the small break size is 640 pixels as outlined there so if it goes below 640 that's when um this no longer applies it so it only applies at 6 41 and larger and the reason i'm doing that is because we want this to be responsive and this is really the only responsive css we need because if it gets larger we want to apply that constraint but if it's smaller it doesn't matter if it is full screen or full width now the next thing that we're going to do is we actually want to set the um another i guess setting for our form for the actual box shadow so we do need actually one more div here so i'll go ahead and add that here we're now four layers deep and i probably could actually put it on that div but i'm just gonna add one more to kind of um now actually i think we do need this div so for this div the class names that we're going to be working with are going to be here we want to set the background as white because we're on a light gray background we want it to stand out a little bit we had a a padding y of 14 meaning the the top and bottom padding and then we have a padding of x of 16 meaning the left left and right padding and we're using the box shadow that we created earlier for our form that is basically that custom box shadow and then you could you could also use you know whatever default box shadows come but i like this this one that i configured especially and then we have rounded so basically we want the um the form corners to be rounded so if i go ahead and save that we'll go ahead and take another look and now we see that we have a much nicer looking you know component if i sign out it looks like we're getting an error oh it just needs to be set user anyway so let's go back to profile um basically now we see that we have our constraints added with our styling and we can now maybe start adding some styling to those ui components i'm sorry for those social social components so to do that let's go into sign in and start adding some styles so the first thing i might want to do is have some type of heading that says sign into your account and here we'll add some styles that we're going to be using across our app we're going to be using this text 3xl and the font black so now we're getting this nice bold effect here the next thing we want to do is let's have some styling for our buttons so um the styling that we're going to be using for our buttons is going to look something like this well actually you know what since we're having these social buttons let's actually use some um social social buttons and to do that we're gonna actually need some icons so i'm gonna go ahead and maybe stop this and we'll go ahead and install react icons okay cool so now that we have those going um we might even take these out and put them in a spa on their own component so we'll have social sign and then we'll just like import that here because we're going to need both username and password sign in as well as social sign in so we can actually just maybe copy this and copy that and instead of that we can just render this and refresh that real quick all right so um let's go ahead and add some styling so i'm going to go ahead and import first of all well let's go to social sign in i'm going to import the fun awesome google and font awesome facebook icons from react icons the next thing i'll do is for the main container i'll add some flexbox styling so when i say display flex and the flex layout to be column now for the buttons we can actually use a couple of different styles the first thing that we're going to do is let's see here well actually i don't need this sign into your account i can just remove that um for the button itself we're going to wrap a div and we're not going to be applying the styling directly to the button we're just going to say we don't want an outline for the button and we want to add a margin top of 10. and for the button itself we'll just be wrapping a div and maybe actually a paragraph for the outside div this is kind of going to be where we add all the styling for the button itself we want to say we want to have the div set as flexbox because we're going to be having two items stacked on top of each other um or actually in this case they're going to be laid out left to right since we're not using flexbox horizontal we're using column direction which is by default uh we're going to be you know giving giving us horizontal layout we want a border of one pixel gray 300 color we have a padding of two we're um giving it a lot of rounded roundedness so we're basically saying we want the whole button to be round and we're gonna be giving like a nice white background with a nice light gray border um we're centering everything because we're wanting to have like a nice big button with the inside being centered so we have the both vertical and horizontal centering going on with item center and justify center and then the last thing we're going to need to do is go ahead and use that font awesome so for google we can use font awesome google and i'm going to set the size to 38 and um i want to set the color of the icon itself because by default it's going to be black so i can say i want it to be this red 600 color and we can do something similar for our other button so i'm going to kind of copy this paste it here and of course we're going to change up a few things but i can copy and paste that there and this is going to be fun awesome facebook for the class name we want to be text blue 600 and i think that's it yeah so we're wrapping yeah looks all good so i'm going to go ahead and save that and just go ahead and refresh and see how this looks okay we're getting somewhere um not too crazy with how close the the buttons are to each other so whoops so we're gonna add some margin so for this button i'm going to go ahead and add a well actually i can probably add this same styles that i have here but instead of margin 10 we can say i'm something i'm margin for and then for the button itself for the text within the button itself i'll set the margin left of three and there we go that looks a lot nicer so we should be able to you know click there and sign in with facebook and google so we have that going for us um so we're pretty much done with the social sign-in but we now need to create a form for manual sign-in so to do that we're going to go back to sign in so we have our social sign-in going on we're going to be receiving props we're going to have an on change handler and we're going to have a set uistate function and basically what we want to start doing is building out this form so what we're going to first do is have the basic title for signing in oh it looks like i actually may have had that and deleted that at some point but either way let's bring that back so i want to say sign into your account i think i had moved it and then deleted it from the from the other component the next thing we want to do is we want to have an input now we're going to be rewriting the same input stuff over and over and over so i think it makes sense to have a custom input component that we can just reuse so i'll go ahead and create a new file here called input.js and here we're just going to have a basic input so the input is going to take and you know whatever props that are passed to and just spread over those that way we can kind of reuse the component and we don't really have to worry about manually passing each one the main thing here though that we're thinking of is the class name because we want to have like that that styling but we won't have to re repeat the styling over and over and over so i can save that input and i can go into and sign in and i can say import input from input and then now we can just start using it so what we're going to do is we'll go ahead and create a div with an input and a label and the label is going to be for the email address for here and then we're going to have another one for the password and then we're going to have a button for signing in so for this div we're going to go ahead and set some margin top of 10 and then for this one we'll set the margin top something like four for the label the only thing we want to do is set the text as small so we're saying text sm which basically gives us some some small text and for the input the only two props that we need to pass in are the name and the on change handler the only change handler is going to be passed in you know as a prop and then the name is going to be passed into the event when the unchanged handler gets gets fired so here i should be able to do the same thing but for this it's going to be password and then i should say type is equal password and this is going to be passed down as a prop of course and for the sign in button we're gonna go ahead and set some nice styling there as well we want the text to be white we want the width to be full we want the margin top to be six the background to be this pink color we want to have pad padding of three and then rounded corners and then for the on click handler we actually need to have a function called simon that needs to be passed in as a prop and then we will be creating that function in just a moment and then i guess the only other thing that we need to be working with in just a moment is a way to kind of toggle between different ui states so for instance um if they forgot their password or if they don't have an account yet we might want to account for that so to do that below the social sign-in the first thing that we're going to do is we're going to be adding a message saying i don't have an account then you can sign up and then basically what this is going to do it's going to set the ui state to be set to sign up for the for this we're setting some basic styling so we're saying we want the margin top to be 12 we want the text to be small and then we want the font to be um light and then for the span that's going to be kind of going within this paragraph and the font light by the way is like a light um it's not heavy it's kind of like lighter you know font weight for within this band though we're going to basically be setting the color to this text pink to kind of highlight it and we want the cursor to be pointer since it's not really a button and we're doing it inline probably yeah this makes sense maybe you should be setting it as a button i don't know but for this it should be fun and we're setting that role as a button so hopefully that'll be good for accessibility um and then the on click handler is going to be calling set ui state setting the ui states to be that and then we're going to also be having you know the forgot your password label so let's go ahead and get that as well so here within the password we might want to go ahead and set that here so we might want to say something like forgot your password question mark and then we have a method or a function called you know set ui state that sets the ui state to forgot password which kind of shows them the forgot password form that we have not yet created um this span has the same thing as this other one i believe except maybe the text is like pink 500 but it should be the same so we'll just set that as 600 margin left of eight and then um when i'm sorry um the margin left is actually 48 but when it's um small the margin left is eight so the responsiveness here is kind of like um when it's when the form is a lot smaller we want to have less margin because we're kind of pushing it to the right a better approach here might be to kind of float it to the right or maybe have some flex box or something like that but for this should be fine so with that being said let's go ahead and save our sign in form and see what we have now so it looks a lot better um we're still getting some overflow from forgot your password so let's bump this down to like 42 or something like that let's play around with that a little bit okay 44. so now we have a pretty good looking sign-in form but if someone clicks on one of these buttons like forgot your password or sign up and you know what forgot your password looks really huge so let's update that to make that smaller that's pretty good um yeah that's fine so anyway if we click on forgot your password we're going to see that we don't have any ui state if we click on sign up we also don't have any ui that's because we haven't you know created those forms yet so to me the next logical form would be sign up because we want to allow people to you know sign up so let's go ahead and start getting that code ready so to do that we'll create a component called signup.js and we'll go ahead and maybe steal some code from sign in actually we don't need social assignment but we do need author input and then i might even steal some of this code here so sign up um they're not going to need this span for forgot your password because they're not going to be even signed up yet right and let's see here what else we have so we have the email we have the password we have signed in so this should be sun up and then we can say have an account sign in we're getting somewhere um this function should be sun up put the on click handler there and i can say sign up for an account okay i'll go ahead and save that see what we have going on here so i'm going to refresh okay so we we're not rendering it i think that's because in profile we don't even have it yet so let's go ahead and import that here and i'm going to say if the ui state is equal to sign up let's go ahead and show the sign up of form i'm importing that from the wrong place let's try that again and boom we have our sign up for an account so that's looking pretty good so sign up sign in looks like our our off state isn't oh yeah so we we need to also pass those props in so these same props you know we're pretty much going to be passing those into all the components so we have that on off i mean that on change in the set ui state so let's try that again sign up sign in forgot password okay cool um there are a couple of other things that we need to keep up with though so for instance once they sign up they need to confirm their sign up so let's go ahead and create that because we're gonna need to basically have mfa going on right for that initial sign up so i'm going to go ahead and copy all that stuff from sign up and i'm going to paste it here to confirm sign up um for the stuff that we're going to collect from them i don't think we need their password i think the only thing that we're going to need it's going to be pretty small see the button maybe we'll have a way for them to cancel out so let's go ahead and add a basic button for them to cancel out for this button um we're just going to be using we're not going to be setting the pink background for this button for the cancel button it's going to be kind of a white background just like some normal text but we'll be using the text color of pink and i think i need to be more consistent here so i'll use text pink everywhere now for confirm sign up this is going to be a scenario where they kind of get a mfa code you know sent to them in an email and then they're going to need to kind of input that somewhere so what they're basically going to be doing is having an auth code so for the name this is going to be auth code and this is going to be their confirmation code or whatever you want to call it and that's going to be confirm your account and basically they're going to be shown this when when they confirm their account essentially right so on click is going to be confirm sign up and then i need to set this to confirm sign up yeah and then for the cancel we're setting the ui state back to you know basically um the sign in state so the only other two use cases i think we need to consider our forgot password and forgot password submit so if the user forgets their password they get they're given a form where they can kind of put in their email and then we send them the confirmation code for them to then reset the password so they're given one screen for their email and then they're given another screen for their confirmation code and their new password so if we want to implement that we need to have a new file for let's see here confirm well yeah well i guess forgot password and then forgot password submit or something like that forgot password is basically going to be something like confirm in the sense that they're just gonna be given one one form and i think the forum is gonna be enter well they're going to need to enter their email forgot password start here whatever we'll put something like that so for the button here we're gonna say forgot password and then we can say [Music] reset password and then for the forgot password submits or was that the forgot password submit that was if i forgot so i'll just paste that there and we're going to be working on updating the forgot password submit and i'll rename this to be forgot password so forgot password submit we're going to need to say submit new password and for the labels they're going to be given a chance to set their confirmation code and their new password and then we're going to say confirm new password and then i think at this point we don't want to give them a chance to cancel out at this point they should have their confirmation code and they should be able to go ahead and use it so confirmation code auth code we're not using set ui state i think we're good um let's go back here and refresh and let's try to use these components now so we click forgot password we want to kind of render that new component so to do so we're going to go ahead and import those new components here so forgot password and forgot password submits and we can check to see if the auth state is equal to forgot password or the ui state actually let's not do that there let's let's go down kind of make it more of a flow so sign up and then we're going to do confirm sign up i don't even know if i've imported that but we will in just a moment so sign up sign in signed in and i think then we'll do the forgot password and forgot password submit here all right so um the next thing we want to do is i guess we want to go ahead and make sure we pass in all the props that we need so when i set on chain channeler and set ui state um i think we only need the on change handler for this submit and then for confirm sign up let's go ahead and import that oh we already did import that that's good or maybe i think it automatically did that for us and um pass in whatever handlers that we need so we need on change confirm sign up and set ui state okay yeah we haven't made any of those functions yet for actually interacting with amplify auth but we will in just a moment we're getting we're getting along though so let's start playing around with some of our ui state again to kind of make sure all this stuff is working so if i choose forgot password then i'm able to you know start resetting my password and i see rest password so obviously misspelled something so let's see if i can find it there we go reset password all right so i guess the the next thing we might want to do is test signing up a user and we're going to basically be needing all these different functions to kind of work with amplify auth category so what i want to do is have a async function for all these different methods so sign up confirm sign up and maybe of course i spelled that wrong maybe i'll just copy and paste this for each one so sign in for got password and forgot password submit am i missing something i don't know maybe sign up confirm sign up sign in forgot password forgot password submit so one two three four five looks like i have five methods here so that's good so for signing up we're gonna do like a bunch of try catch blocks so let's maybe even copy and paste those around since we're gonna be using the same now we don't have to keep writing this over and over and over and honestly probably should have just done something like this to make this error message concise so let me let me actually copy and paste that with the error message okay all right next i want to say for each method it's going to be a little different so for signing up i want to say awaits off dot sign up and here we need to pass in the username i guess in this case the email the password and we should be good to go but since we have this ui state let's go ahead and destructure that since we're going to be using the email password and auth code off of this so we can now just start referencing email password and off code so for signing up we're going to be needing the email the password and then we're going to be needing to set something called attributes which is a map or an object and this is going to again also going to contain the email now in this case we basically are going to be setting the username as the email believe it or not and this is kind of how amplify is going to be expecting to have like the the main i guess hold on one second i'm actually referencing some code here but basically that's going to be basically the main identifier for that user yes so it's going to be the username key is going to be set to the email and we're also passing the email as an attribute anyway so if this works if if all that signup works we should be able to now get to this line and what we can now do is say set ui state because we want to say confirm sign up because if this is successful then that means we need to allow the user to set their mfa code and now we can pass sign up into the sign up function so sign up sign up i'm just making sure it's been passed in properly because i see it's not highlighted or it is it looks dark like it's not being used yet but some unless i'm incorrect here let's see anyway we'll keep going um the next thing we're going to do is use confirm sign up so let's go ahead and pass that down as well we'll also pass in sign in and we'll do the same for the rest of these okay um for confirm sign up we're going to now be needing to say awaits auth dot confirm sign up and here we're going to be passing in the email and the auth code now if this is successful we can now call set ui state and we're going to be basically setting the uic to be signed in and we might also want to go ahead and reset the ui state for the currently signed in user because at this point there will be a sign in user so instead of having check user inside the use effect we might even move it outside the use effect hook and then this way we can set it we can use it whenever we'd like so i guess we could do at this point would be something like called check user and then this would kind of check if the user is signed in and if it is update the ui to kind of show the proper ui um well actually at this point they're still not signed in so we might want to just call sign in and since we haven't removed any of the ui state then then we should be good to go and then we can kind of figure out how to update the currently signed in user in just a moment now for sign in we're going to call awaits auth.sign in passing in the username and the password and then if they are signed in we can call set ui state so that to be signed in and if they're not nothing is going to happen which is exactly right so we have we should basically have our sign in and sign up flow at least possibly working so let's go ahead and save this and i guess test it out looks like i'm using ui state there when it should be off state which is exactly a big big fat bug all right so um sign up sign in looks looking good so we don't have an account yet for our email so i'm gonna try this out i mean we'll see i mean i'm sure there's a bug or something but we we should be most of the way there okay so reference error username is not defined let's try that let's see what's going on here this should be email first of all we don't really have a username so i don't know if that was the error um oh and also see where it says sign into your account when i should be signing up well anyway let's try that one more time okay so maybe this isn't working or maybe this is working okay waiting waiting confirm sign up okay that's kind of where we're at where it is not working yet so let's let's go back and see what we have going on oh it looks like we misspelled the prop here so i'll go ahead and save that and i'm going to go into cognito and go ahead and delete that user i just created and then we're going to try again from the beginning so i'll go ahead and click sign up check my confirmation code all right so we are getting somewhere i guess but we're getting a little bit of an error probably because i'm probably looking for a user when there is no user so basically we're saying user.attributes.email so i might want to say you know ui state is equal signed in and user and then show that because that way we know there's like a user and they're signed in so i'm gonna okay so but but once we're signed in you know it keeps the user session so we see that we're we're still signed in which is pretty cool so if i refresh and all that so if i sign out then we're brought back here so we got a little bit going on um let's now try to sign in okay something's going on but it looks like we have some issues there so i think when we sign in um we want to check user as well because you know we want to go ahead and update that user again we could we could set up a listener somewhere that would actually never need for us to call check user again either way it's kind of you know a good a good approach either way i think just depending on how much code you want to write so let's try signing in now that we have that check user function there we go so our sign up flow is working our sign in flow is working the last thing we need to do is get our forgot password flow working so to do that we're going to be working with um auth.forgot password i have to go look up this api real quick i think all we need to do is say awaits auth.forgot password and pass in the email address of the user that that's trying to get their password reset and then we can say set ui state for forgot password submits and then for forgot password submit we could say awaits let's see here i think it's auth dot forgot password submit and here we're going to be passing in the email the auth code and the new password and then if that is successful we'll call set ui state and we'll set the ui state to sign in because that means we have their new password or i guess we could maybe sign them in because we have all that stuff here let's go ahead and sign them in automatically i don't know what's the best practice actually let's let's make them sign in for now so forgot password submit looks like we're passing all the proper props down so right now i have a user and i have a password but i want to reset that password so let's try that and click on forgot password reset password okay so i should be getting confirmation good and my new password should be whatever something new so i'm gonna go ahead and submit my new password okay looks like it's working all right so looks like all of my different authentication stuff is working so if i sign in with facebook i'm able to sign in and get redirected if i go to oops if i go to my profile page after signing with facebook oh i'm not getting not staying signed in so i need to see what's going on there so let's let's see what's going on with that so let's try signing in with facebook going to profile actually it does look like we're signed in and then we're going to go to um try that with google and if we get our profile it looks like we're signed in okay cool so what we might want to do is go ahead and create that protected route and we might want to say if the user is sign in we want to allow them to kind of see the page and if they're not we don't so some of the same logic that we're going to be using in check user would apply there as well so let's copy some of that and go ahead and import off from aws amplify and import use state and use effect from react and we'll have that use effect hook there we'll go ahead and return and we might say if if there is no user we'll return null because when the page initially loads we're going to be checking for the user and if there is a user we'll return and if not we want to do some redirect up here so we might want to go ahead and say const user set user is equal to um use state null and then we're going to be setting the user here when we check the user we're not going to have a set ui state we don't really need that because we're only going to have one ui say that is sign in user maybe the user is not signed in so we have user and set user when the app loads we're going to need to use the router so we can import use router from next router and then here we can kind of say const router is equal to use router and what we want to do is dynamically route so we want to say if the user is not signed in we want to um say router dot let's see where is it navigate now let's go ahead and look and see how to dynamically navigate i forgot what the how to do this dynamic or programmatic i think is what they call it next router router.push okay that's what it is we want to say router.push off or profile actually because if they're not signed in we want to redirect them and you could also actually use um get server side props um for checking the user and and not even return anything um so we're not gonna i don't think go into that but you could do that so with that being said let's try to navigate to this new protected route so we're signed in so you know we expect to be able to see it but let's sign out and then try to navigate to the protected route um it looks like we're you know getting redirected to the profile route it looks like we have some issues with amplify auth being configured i'm not sure if that's just maybe we need to um import configure amplify or something i don't know maybe it's just like a message that's not too big a deal i don't know but um either way the functionality seems to be working because if we if we navigate to protect it okay there we go it seems to be going away now so if we navigate to protect it we're unable to see it but if we sign in and then we navigate to protected then we see the protected route so protector routes are working you can get access to now the user on the server or in an api route if you would like so we might want to test that out so to kind of enable ssr support i mean we don't really need it for this app but let's say you wanted to use it to enable ssr support you would need to just set ssr to true when you call amplify.configure so here we could say dot dot config ssr true and then this makes the app ssr aware now if what if we wanted to now use an api route to kind of get the sound in user and this would also work in a server rendered route we could import i think it's called with ssr context from aws simplify and now that i'm doing that let me make sure yeah there it goes with ssr context and then what we can now say is const auth is equal to with ssr contacts passing in the request and now we can say const user or we can say maybe try catch but let's just for this demo say const user is equal to awaits auth.current authenticated user and then i guess we need to go ahead and import auth and then for the response json maybe we could return the user let's try that oh okay i don't need to import it off what am i talking about that's where we're getting the auth from from the with ssr context okay um let's go ahead and try that there might be something i'm missing here but this is the general idea so since we're since we are signed in let's try to go to slash api hello also i might want to go ahead and import configure amplify but um but either way we should be not getting in a 404 because we do have that api route i might just try to oh it looks like i'm getting some error oh because i'm saying a weight here and it's not an async function let's try that again and then i guess we could also maybe log the user out and that would just show up in the terminal so let's try that one more time okay it says the user is not authenticated pretty sure the user is authenticated so there's probably something i'm missing here so well i guess i can go the docs i need to pass in the request i believe like that because you can also pass in other stuff so let's try that one more time and maybe i also want to sign out and then sign back in because i didn't have that ssr stuff set up before all right so slash api slash hello there we go we have all the information about the sign-in user and then you'll see that it also got printed out to the to the console so the ssr support is now working on an api route so let's say we had an api that we wanted to be protected only a sounding user can fetch data from this for with for use within the app or we're working with a server rendered route that would only work for that user that is signed in now this was a lot one of the really powerful things about amplify is that you can use these ui component libraries that actually scaffold out a lot of this stuff for you so let's try one of those out real quick and kind of show how much easier all this could have been what i'm going to create now is an amplify off page dot js and what we're going to do is let's go ahead and install aws amplifies ui react so i'm going to install that and for this components let's go ahead and import the um with authenticator is what we're going to import from from aws amplify ui react we're just going to go ahead and create another profile right and then instead of just exporting the default we're going to wrap it in this with authenticator and then here we're just going to return div and we might even snatch up some of the functionality we've been using in these other places go ahead and close a lot of these other files we're not using and then for the um return here we're just going to say welcome user user.attributes.email i'm going to say npm run dev and then um i guess we don't really have that or that we do need a set user function anyway so we pretty much only have now 26 lines of code and now we should be able to go to this new amplify off page and see that we have an authentication flow kind of set up for us it's probably not as pretty as the one we just built but it should be a working authentication flow and maybe i need to go ahead and actually configure amplify that's right because i have not configured that anywhere at the root i keep forgetting that um misspelled something try that again so okay so yeah we're signed in so let's go ahead and sign out and then try that again and you'll see that we have like this authentication flow and i'm kind of zoomed in so it's kind of big but we have a username password flow [Music] we also can let's go back and use the hosted ui for a google or facebook sign in so i could click sign in with aws and i can say continue with google and this should now allow me to kind of sign in that way all right well uh that was a lot and that's it i don't think i'm gonna go for anything else so i hope you learned something and i hope you kind of um you know i guess caught on to a couple of new things maybe from all the stuff that we just went over either with tailwind or with amplify now all of the code for this is located in the comments here there's also going to be a blog post that goes along with this so this is a very long video so if you lasted this this long i appreciate you watching again i hope you learned something and i hope you enjoyed this if you're not already please subscribe to my channel and i will see you next time thank you
Info
Channel: Nader Dabit
Views: 7,544
Rating: 4.9569893 out of 5
Keywords: next.js, nextjs, serverless, jamstack, aws amplify, aws, tailwind, tailwindcss, javascript, react
Id: 4P2jJRbtTck
Channel Id: undefined
Length: 93min 24sec (5604 seconds)
Published: Thu Jan 28 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.