Google OAuth with Devise and Omniauth - clearbnb - Part 2

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up welcome back you're watching the second episode in a series all about building out a short-term rental marketplace in this episode we're going to break ground create a brand new rails app and start setting up some authentication so let's dive into that so i'm going to say rails new clear bnb we're going to skip tests because we're going to add our spec later and i'm going to set the database to postgresql and i think that's it okay i need to set my node environment to 14.7.1 and i'm going to say rails web packer install again because i did not have that version of node i had a super old version of node and it kind of fails the webpacker install say rails db colon create to create our database so we have we can keep track of everything as we go and then the next thing we want to do is open up our gem file and we're going to add the gem device this is going to be our authentication tool gem device okay bundle install device is a ruby gem that is a super great tool for authentication uh it's a flexible authentication solution for rails built on uh warden so there's a bunch of different tools that we can use we can do database authenticatable omniauth able meaning that we can log in with other accounts i think we might actually want omni authorable at some point where we can omni auth into for instance like a google account i think that would be a really powerful tool confirmable sending an email confirmation with instructions i think that's important recoverable so there's a lot of different tools here that we are going to want to probably use as part of our system in a lot of demos i don't add too many of these modules because oftentimes it's just a really simple demo you can sort of just log in with username and password or email and password and that's enough to kind of show off the demo but for this i think we really do want quite a bit of flexibility and functionality and so let's take a look at the installation um getting started so let's see okay so we've added that we've added the devise gem the next step is to do rails g device colon install and we have another episode in this channel about setting up device but this time we're going to go through in a little bit more depth okay so then there's some steps that are spit out here at the top so we want to open up environment development and go down to the mailer config and drop in this line that's step one all right step two is ensure you have defined a root url something in config routes root two home slash index um okay so let's we actually don't have a home page yet so i'm going to create a static pages controller and i'm going to give it a home page and this will be sort of the landing page for the site where it will probably have a big input box that allows you to type in where you want to search for vacation rental so i've got this this static pages tool allows you to kind of like build out almost like marketing pages your privacy your terms of service things like that that don't naturally fit in other places with rails so now we can open up our routes file here and we can say route to static pages home okay what else we got step three was to ensure you have flash messages in application html erb so we'll open that up all right here inside we'll just drop it in at the top for now we'll come back and style all of this later and then the final step was to generate the devise views which is not necessarily required but we're going to want control over the look and feel of this so i'm going to say rails g device views okay great and the next thing we need to do is let's say let's make a commit that says we've installed devise all right the next thing is that we're going to need to actually have some sort of user model so when we're configuring the model we want to say i think it's rails g device user let's see rails g yeah okay so rails g device and then the model name so we don't actually have a model yet so let's create a user model rails g model user um and yeah so this for for now we're just going to leave this empty we're going to create an empty model called user we'll add all the device fields to it and then we're going to need to come back and add more to it later i almost wonder too if we want to specify some sort of user type or something where we could have either guest or host but i think in practice a user could be both right they could they could be um they could be taking actions as a guest and going out and traveling or they could be also hosting their place so maybe that doesn't actually matter for now so we'll just create an empty model now we want to say rake or rails db migrate to migrate that'll actually create the table and then we're going to say rails g device user and that should create the device yeah a migration that will add the device columns to the user so we can take a look at this and inside of the migration you'll notice that there's a bunch of these modules that have commented out fields that are not actually supported right now so we've got trackable let's actually look through all of these different fields and what they do so we've got trackable um what is this track sign in count time stamps and i p address that does feel valuable just so that we when you're when you're working through disputes between a guest and a host sometimes it'll be valuable to know like okay the person logged in and they saw something or they did something so just having some sort of record of that seems good we've got confirmable so confirmable sends email with confirmation instructions verifies whether the account is already confirmed during sign in that sounds valuable right we don't want people just trying to like keep signing up and spamming you know different uh different email addresses or something um or you know we want to make sure that the person who's logged in has access to the email that they just signed up with and then lockable locks an account after a specified number of failed sign-in attempts so you can unlock via email or after a specified period that seems valuable so that we can make sure that if someone is you know testing passwords where we can lock out the you know someone who's just trying to yeah do brute force password testing um okay and let's see td time stamps null so i think yeah when we created the user originally we did have timestamps so that's fine um all right then we've also got omni author and there's a there's several other sort of uh there are several other tools that are not i don't think are necessarily represented here so let's um we'll uncomment the confirmation and unlock token indexes because those will help with the speed when you're going through the confirmation flow or the unlock flow yeah so we're just going to go with these default fields we've commented in all of them we're going to say rails db migrate and we'll take a look okay so let's fire this up rails actually let's also look at the routes file and there should have been okay so device for users so i'm actually going to move this down a little bit and say rails server we'll probably want to keep that at the bottom long term uh i think so okay just to keep it that's i don't know that's one of the ways that i like to keep it organized is sort of having your root at the very top then a bunch of your resources route definitions and at the bottom any engines or you know other namespaces and things okay so slash user slash sign up maybe okay so this is going to be our sign up page so if we wanted to enable omni authorable um devise four okay so this is probably implemented inside of the user model so we've got uh devise and here's all the different things that are uh enabled what's what's interesting here is that in the documentation it says devise for but here just says devise are we looking at different things um okay not sure all right so uh all right so but we do actually need to add these other we want to add these other uh modules so we can say confirmable lockable time outable trackable and omni authorable okay if we're using omniauth we need to configure the we need to configure omniauth inside of initializer's device so that we can specify which providers we want to be able to log in with this is really just googling around so we're going to look for something that has relatively recent commits so this is two months ago and it's on v1 and it's public it's got 1.3 k stars that looks pretty decent so here we can add this gem to our gem file and we'll put this right under devise and here we can say this is authentication just to keep this organized well let's just bundle install this all right then we need to open up um the initial config initializers directory and in here there is devise.rb where you are it comes with a bunch of configuration that you're able to add and so this follows sort of the same pattern as the uh um production and then like the environment config where we have device setup due and then it passes in config to the block here where we can set different arguments on this and so what we want to set is we want to enable um google so let's see okay so this is the omniauth section so we're going to add a new omniauth provider and in this case we're going to add google but i'm not sure exactly how we want to set this up or what the name of the provider is okay here we go so the provider is google oauth2 and then we need to give it a client id and a client secret client id and client secret and then we have scopes do we need any scopes while developing your application if you change the scope in the initializer you'll need to restart your app server remember that either email or profile scope is required so either we need the email or profile let's just say the email scope that sounds like a little bit more limited and then we need to find our app id and app secret so let's actually go to okay so we go to consoledevelopers.google.com so i'm going to create a brand new project called clear b b and b clear b and b maybe it doesn't i don't know what the capitalization is going to be yet um and so we will um yeah this doesn't have any organization we'll say create okay and then we're gonna switch to that project okay so we are we're looking at the clear bnb project we have to configure the oauth consent screen for now we'll make it external i think we're going to have to actually submit it if we want people to use this support email will be just email me at the beginning we don't have an app logo the domain we don't have a home page yet but for now i'll just say dot dev and it'll be cgive dot dev slash privacy and um slash terms and then when a domain is using the consent screen okay so add that domain sure wait yeah okay i guess sure must be pre-registered here if your app needs to go through verification go to google search console okay the developer contact is me and save and continue i think that might work all right so adam removes scopes we want the let's see so see your primary google email address or see your personal info including any personal information you've made publicly available i think we just want the email address for now that's probably going to be just fine and then we can say update so this userinfo.email scope is interesting because i don't remember exactly if that's how we need to specify it or not okay we're going to say save and continue and we're going to add a test user i'll add myself and that's it for now save and continue back to the dashboard okay so now that we have configured the oauth consent screen we should be able to create we should be able to create credentials for this oauth 2 client ids so we need to create some credentials and we're going to use the oauth client id the application type is going to be a web application and this is going to be clear bnb the authorized javascript origins uh i don't think yeah i think we're going to need a redirect uri so this is going to be localhost it's actually just http localhost3000 something all right so we're going to use uh slash user slash auth google oauth 2 callback we'll see if this works as our callback url is our actual client id and client secret so now what i want to do is say rails credentials colon edit and i'm going to set my google credentials here and we'll say um client id is this and client secret is this we say okay client id and client secret setup so now we should be able to go back into our device initializer and where it says app id we want to replace this with rails.credentials rails.application.credentials.google at client id and same thing here so rails.application.credentii client secret and that should give us the client id and client secret from our secret credentials that are encrypted and okay so let's see if this works and okay so immediately you see that now we have this sign in with google oauth2 we didn't actually change any of the ui but because we have this provider configured we should be able to click on this button could not authenticate you because of an authenticity error okay so that's interesting i'm not sure what's going on there let's head over to the server attack prevented from on the auth authenticity token protection hmm let's see authentication failure authentication authenticity error forbidden so let's number one let's make sure that our credentials all look good and then from the dashboard here i wonder if we're going to be able to see any errors it doesn't look like we see any errors um so attack prevented from authenticity token okay so let's see what this error is all about okay the sh the short answer is because your credentials are wrong so you're calling the end on on the first but not the second argument better answer is use a better mouse trap okay so here it looks like they've got the domain name as part of as part of what's being passed so we've got the strategy config omniauth okay so we've got the strategy we've got the scope we've got the access type and image okay so there's a little bit more here than what we configured all right so what we've got going on right now is we are calling all right so we've got our we've got the scope we don't have the name um maybe we should say name is google and maybe we want to say the axis type is offline and for the image aspect ratio square i'm not sure what that's about but our in our scope we just have the email and i think that's okay so let's see oh the one other thing was that this wasn't using we're not passing the strategy class so maybe we want to also do that strategy class so let's see if this helps the page here sign in with google could not authenticate google because authenticity error yeah authentication failure authenticity error forbidden so what's going on here let's let's check and make sure that our config is correct so rates actually i want to add pry rails so bundle add pry rails so that i can change into the device config in the device settings i guess i also want to put this i don't want to put it just directly at the bottom i want to keep it in just development and test so i can now say rails console and i should be able to look at those device settings so cd devise and maybe can i look at config let's look at this again um so if i can i look at omnioth providers we've got google okay omnioff configs i think that should be my credentials if i'm not mistaken yep those are my credentials okay and then what else do we have going on here is that actually correct yeah that's exactly what we've got okay and then if this one is correct that one looks good okay so our client id and our client secret are correct we keep getting this authenticity error this stack overflow post suggests that using omniauth rails csrf protection is going to help so let's take a look so we're going to we just added this gem to our gem file now we need a bundle install and we will refresh our assignment page click on sign in with google hey we are redirected but uh or at least we're getting we're getting closer so we have a redirect uri mismatch so try to figure out what we'd like to do is try to figure out why we are redirecting to something different ah okay so the redirect uri that we specified was users auth google callback but in the dashboard we set a different um we set a different callback url so i think we need to edit this yeah so this instead of you okay yeah so this should be slash users auth google callback it's because we set that name on the provider um okay so now let's head back over to our login page here okay go to users sign up sign in with google oh look at that we're redirected continue with clearbnb okay that looks pretty good we're going to click on my profile here could not authenticate you from google because the action google could not be fined could not be found for the devise omniauth callbacks controller okay great so the next step is we need to actually go create this controller so the omni-auth callbacks controller so here what we want to do is open up let's see rails g controller and the one that it expected us to use was devise slash omniauth callbacks controller but in a lot of the instructions it says to override that and when you're in your routes you specify the omniauth callbacks pointing to your own callbacks controller that's nested under the user's namespace so we're going to call it users slash um omniauth callbacks okay so we're creating a brand new controller and we're using this user's slash so that the controller is namespaced so if we open this thing up you'll notice that at the top now we have users colon colon so that is a name spaced controller there we need to define the google action and in in here this is where we're going to do the actual authentication so we're going to try to find find the user from omniauth if they're persisted we're going to sign in if not we're going to try to sign them up right okay so here we've got the method that we would add to the user class so we can go to the user model and add this new method from omni-auth and this says where the provider is auth.provider and uid is off.uid first or create we're going to set their email address password their name and their image and if we're using confirmable you have to also validate the email address and so we could we could we could skip the confirmation the email address confirmation because we know if they're logging in from google that is like definitely going to be their email because they're authenticated as the person already okay so then what we want to do here is this code right so we're gonna copy we're gonna essentially copy the contents of this and then we also want this method here the failure method in case um that oauth fails all right and so okay so we're looking up the user from omni auth this should find or create the user uh and we have implemented it if the users persisted sign them in and redirect sign in and redirect okay and then we're going to set the flash message to they successfully logged in as google um and then session devise google data is going to be all of this except for the extra stuff okay and then we're going to redirect to the new user registration flow uh okay let's let's see if that helps us out um i know a lot of that was just boilerplate so we'll see because i don't i don't think necessarily it's gonna be perfect all right so we're gonna start over all right sign in with google the action google could not be found for devise omni auth callbacks can ah because we need to also update the all right so we also need to update the controller here or i'm sorry the route to use this um so that we're specifying when we're using the omniauth callbacks controller it's going here instead of to the devise omniauthcallbacks all right so let's try it again sign in with google all right hey i think we are logged in i think we are logged in okay so how would we know if we actually created a cuss or a user so rails c and we will do user.count and we have zero users so what happened here with the with this failure so um users.provider does not exist okay so we didn't actually add the provider column or the uid column to the users table so let's create a new migration rails g migration um we need to add omnioth columns to user and that's going to be the provider and that's a string and we're also going to pass the it's like the auth id or something like that like provider we called it something we'll call it auth id for now but then we'll take a look and see what that is in the user table so we're trying to look them up by their uid uid so we've got the provider and the uid so let's call it uid so add omniof add on the auth columns to you so uid and i think that's also going to be a string let's also make this add index to users on uid add index to users on provider and uid and make i think that should be good that'll make it so that this query where provider blah blah is fast okay if we've got those indexes rails db migrate okay let's try this again slash users slash sign up sign in with google okay we're back to our page here still zero users what happened over here method name equals for user failed okay so uh we don't have let's let's add a let's add name to the user rails image i think we can take off the image for now let's rails db migrate this thing all right here we go third time's a charm sign in with google all right it looks like in our console here we have a 500 and why is this 500 well let's see user.account hey there's one user user.last all right that is me i've got my user id all my stuff is here okay so that that is now successfully creating users so that's great um all right so let's go through the flow again so users sign up you're already signed in users sign out is there a sign out method users log out destroy user session path users sign out yeah that should work oh but we have to send a delete request to it okay so we need to okay so we need to have some button on the home page that allows us to sign out so let's do that so in the application html erb template here at the very top we will have a button to log out and this is going to go to the destroy user session path and the method is going to be delete let's see if this works okay log out successfully signed out and i guess we only need that if we're logged in user signed in okay so if they're signed in they should see it if they're not signed in we shouldn't see it alright so the next step here is we want to go to users sign up and we'll enter in an email and password let's log in with test test no password password sign up a mesh okay a message with the confirmation link has been sent to your email address please follow that link to activate your account and so in development you can see this email attempting to send right it's being printed out in the logs and so we can see this uh we can see this link here in the email message that was attempted to be sent out locally but that's kind of a pain if you have to like always go into the logs to check it out right or to like see it and so our email was confirmed we're not actually logged in yet but what i wanted to do is before we get too far is i want to add to the gem file inside of development and yeah i'm going to add letter opener because that will automatically open those emails that are being sent they'll open them as html locally so we can at least see them bundle install okay so after we've installed the gem we need to also go to environment development and where we have the mailer we want this to actually perform deliveries and send it to letter opener okay so we're going to copy yeah so we need to tell it that we want to set the delivery method to letter opener and we want to perform deliveries all right all right so we're going to head over to users sign up again and here we're going to say wave 3 at cgiv.dev password password sign up and all right so now this is the email that you would have received welcome you can confirm your account through this link below we click confirm my account now it's confirmed now we can log in so notice where like users sign in here so now we can actually log in we're successfully signed in we uh and yeah we have a logout button here so that looks that's all looking pretty good um all right so now we've got the ability to log in via google or via database authentication all right so we had to update our user to support omni authorable so we had to add the provider and the uid and name columns to the user class we also went into our device initializer and used uh used the config for the google oauth 2 provider here so we set up our google oauth 2 provider we also needed to set up a omniauth callbacks controller where we received the completion of the omnioff authentication flow and were able to find or create a user and then we redirected them we also inside of the user model we had to enable several of these device fields and then we also implemented this from omni-auth static method that helped us find or create the customer by their authentication details all right so that's how we're going to set up authentication we'll probably add a little bit more to this later things like styling those device views is going to be useful but i think at this point we can sort of go back to our list here and check off the box for authentication thanks so much for watching in the next episode we're going to go through creating reading updating and destroying listings as a host uh yeah i hope this is useful for you and uh yeah now you can go and set up your own google omniauth flow with devise and rails cool see in the next one [Music] you
Info
Channel: CJ Avilla
Views: 517
Rating: undefined out of 5
Keywords: cjav_dev, web development tutorials, web development for beginners, vim, ruby, rails, javascript, devise, rails tutorial, google oauth, google authentication, rails authentication
Id: Lut1C6CHDCE
Channel Id: undefined
Length: 36min 0sec (2160 seconds)
Published: Wed Sep 29 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.