Laravel Inertia With Socialite

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
~ The content of this video is intended for educational and entertainment purposes. ~ ~ It is NOT production ready. ~ If you are new to the channel, welcome. If you're not new, welcome back. Today I want to go over implementing Socialite within our Laravel application, and if you don't know what Socialite is, it's basically just an authentication method. It uses Oauth 2 to authenticate using your Facebook, LinkedIn, GitHub, Google. Whatever it is, and that's what we're going to be working on today. Before we get started, what I want to do is go over what I'm using in my project so that you know exactly what I have, and where we're starting from. So in our composer.json, I'm using Laravel Framework 9.19, Laravel Jetstream 2.13. I've got Sanctum, Tightenco/Ziggy, that's for our routing and that's pretty much it for the composer.json. As far as the package.json, I'm using Inertia, Inertia Vue 3, Progress, Forms, Tailwind, all that good stuff. This Tailwind stuff is pretty much irrelevant as we're not really going to be working on too much design, but I am using Vite with my implementation, as that is the default installation as of recording this video. Now if we go ahead and take a look at the Laravel documentation, and head all the way down to where the packages are listed, you see that we have the Socialite tab right here, and that's the page that I'm on. I want to go ahead and head over to the installation, and then I am going to copy that, and then we'll bring that into our project, and since I'm using Sail, I'll have to do Sail and paste that in. Press enter, and let that run. Okay, very good. Now that that's done, let's head back to the documentation. Okay, and one more thing that I want to show you. In this introduction section right here, you see the Oauth providers that it currently has within this Socialite installation. So you can use Facebook, Twitter, LinkedIn, Google, GitHub, GitLab and Bitbucket, and so what I did was I created some accounts to basically show you what it's like to have the same email versus what it's like to have a different email associated with these accounts. So we're going to be doing the Google, GitHub, and I created a GitLab account as well all under the same email to show you how that works. If you want to use other providers other than what's listed right here, you can go ahead and take a look at this Socialite providers link right here, and this is going to bring you to this page, and it's basically the same thing where you can use the different adapters to basically just to use other providers. If we go to get started, you see they have social platform, and they have all of these different accounts that you have. I'm not creating accounts for all of these, but you can just easily check out the documentation. You would basically just have to install whatever the plugin is, so let's say let's say even for -- well let's take a look at Medium. You would have to install this Socialite provider for Medium, and then you'd have to use the credentials for that, and you would need the listener, and this is how you would use it in your controller or however you're going to set that up, and it's really simple to use. It's basically the same thing. This just gives you some more additional information, so whatever provider you're going to be using, you want to use them in your providers, of your service provider, and then use the event listener, and that's pretty much it. But I'm not going to be doing all that. I'm just going to keep it as simple as possible. Once I show you how to do it initially, you'll be able to use these for whatever provider you want. Let's head down. We already did the installation, and now I want to set up our GitHub credentials and we're going to be putting this in the services configuration file. Okay, so now I can go ahead and close this out, and get out of here, and we are going to be looking for the services file. Okay, so we're going to head down, and we are going to drop this right at the bottom. This is going to be the first one which is GitHub, and we're going to have a client ID, client secret. We're going to pull these from our environment variables, and what I want to do is, I'm going to copy this because this redirect, I actually want to use within the environment variable itself. Paste it here, and instead of secret for this one, I'm going to call it redirect. Now I can grab all of these, get rid of this one from here, and we'll go to the .env files and add that. I'll just add them at the bottom here. Okay, and I just need this, this, and this. We'll add our equal sign to these, and the callback URL I'm going to do http localhost, and then I'm going to call it auth GitHub, and the route we'll use is just the callback route. Okay, so now I can get rid of this, and we'll do the same thing for our other providers as well. Copy that, paste it. This one is going to be GitLab. Okay, and this one will just be Google. Okay, let's go ahead and add these two to our environment variables as well. I'm going to copy this, Okay, and GitHub will be GitLab, and part of the callback -- instead of GitHub we'll have GitLab, and for this one we'll call it Google, and the same for this route. Call it Google. Okay, fantastic. Let's head over to the documentation and see if there's anything else that we need. Okay, let's go ahead and scroll down. These are the routes that we're going to need, so I'm going to go ahead and create a controller so that we have all of our social credentials running through the one controller. Then we'll do Sail artisan make controller, and we'll call it social controller. We won't make it resourceful or anything because we're making custom functions. Okay so now that that's done, let's go ahead and drop this, and then we'll go ahead to the web routes and create those links. Since we're using multiple providers, what I find is the easiest way to do it. Instead of creating multiple controllers and multiple routes, I'll just use the two routes that we're going to be needing. One is the redirect and one is the callback, which means that in this route right here, we can say provider, and this will be the redirect and then we'll use the social controller. Okay, and these we don't really need a name for, but what we do need to do is add -- basically we need to fill in this provider. So we're going to say where provider equals, and we have GitHub, GitLab, and Google. Let me drop these down a line so that they're a bit clearer. All this is saying is that, once we hit the route from the front end, it's going to inject the provider that we're going to grab, and it's going to be either one of these three. If you have more, you can add them there as well, and that will be injected into our route. Okay, so let's do the same thing for the callback. This will be callback, and I forgot to add here which function it is. This will be the redirect and this one will be the callback. Okay, let's go ahead and import this. Fantastic! Now before we get into the controller, the first thing that I want to do is I want to create some buttons in our pages so that we have something to go to. The first one will be on the register page, and we'll head down to the end of the form, and I am just going to paste in our links because they're going to include the links for the redirect. Even though we're using Inertia, these have to be external links which is why we're using a tag. As you can see, I have auth GitHub redirect, it has the GitHub icon. The same thing for the Google. The Google icon and the same thing for GitLab, so let's go ahead and also grab this, and we're going to put it in our login page too because it doesn't really matter whether you're using the registration or the login pages. These are still going to be the same functions. Go ahead paste that in, and let's take a look at our pages and see what they look like. Go to the register, and I forgot to run Vite, so let me go ahead and get that started first. Refresh it and try it again. As you can see, we have our links here and we need to grab our credentials, so let's go ahead and start with the GitHub one first. Okay, as you can see I am already logged in. This is the account that I created, and it has the account name. It's nikosdummy6 and this is a Gmail account. So I've opened up several different accounts with the same email so that you can see how that is first. What you want to do is, you want to go down to settings and then once you go all the way down to developer settings, it'll open up another tab where you can click your Oauth app, and this is where you can set up your application. We'll register a new application and I'm going to call it Socialite, and the home page URL that I'm going to be using is localhost, and if you're using Xampp or anything, it'll be colon 8000. That's what you'll put there, and then our callback will be that callback route that we created. So for GitHub, it'll be auth GitHub callback. Okay, we'll go ahead and register the application. As you can see nikosdummy6 is my account we have a new Oauth account so we're going to go ahead and grab this client ID, and then I'll close these. In the GitHub client ID, I'm going to go ahead and paste that in. Okay, and then I also want to create a client secret which you can generate right here. Keep in mind that you will only get to see it once, so if we have to refresh a page, you'll never see the whole secret. You will have to create a new one and delete the other one or however you want to do it. Okay, so I'm going to go ahead and grab the authenticator code for that. So now as you can see we have the client secret right here. I'll go ahead and copy that and I'll go ahead and paste it here, and that should be good for the GitHub. Now let's go ahead to GitLab and set that up. As I said, I created this GitLab account for this demo, so I have no projects in here. I have no code in here. The only thing that I have is the same account so nikosdummy6 and that's at gmail.com as well. Let me see. What we want to do here is, we'll go to preferences, and then we can go to Applications, and just like with GitHub we want to create our own application. So the application name will be Socialite, and our redirect is the http localhost auth GitLab slash callback. Okay, and as you can see there are different scopes here that we'll want to select. We want to first -- we can keep the confidential up here, that's fine. We also need the API, we need the read API, we need the read user, and these are just granting different permissions that will allow our app to use this as a login. Okay, and the next one we want is the email, and then we can go ahead and save the application. This one fortunately will retain the secret so all you'll have to do is just copy it if you want to and then you can go ahead and use it again if you need to. Okay, so the GitLab client secret. Go ahead, paste that in, and then let's go ahead and work on our Google client, and this is my Google. As I said, I created a new one and this is nikosdummy6@gmail.com, and this is my general account, but I'm going to be using this one. Up here on the left hand side. You see we have select the project, so we don't have any projects in here yet. I'm going to go ahead and create a new project, and this will just tell you how many projects you have remaining blah, blah, blah, blah. I'm going to call this again Socialite, and no organization or anything. We're going to go ahead and create. Okay, and this will -- you can see the ones that I was testing out. Okay, so we'll go ahead select that project. This is just a standard dashboard for the Gmail accounts -- of Google accounts, and this is to use the API. So we're going to go ahead to API's overview, and you can see up here that this is the Socialite project that we're working in. We're going to have to set up some credentials, but as you can see it's going to tell you here to configure the Oauth consent screen with that information first. Let's go ahead and do that like we did with the GitHub and the GitLab. This is going to ask us basically what kind of users we're going to be having. We'll say external because we're going to need to use this in order to test out the credentials with that project. We'll go ahead click create, and the app name again will be Socialite. Email, and this should be the email that's in the account. It should be -- that's the only one in the drop down right there. I don't have a logo or anything and the home page we can just do http localhost. Mine is just localhost. Again, if you're using something like Xampp, you'll have to use colon 8000. I'll copy this. We don't have a privacy link set up, so I'm just going to use these and we don't have a terms of service or anything either. Just a quick walk through too, this is basically what it's going to look like when a user tries to authenticate using Google. Okay, let's go ahead and add our domain, and for us it's just going to be localhost, and you can say localhost.com if you want. It doesn't really matter. Then add our email address, save, and continue. Okay great so we're pretty much done with that so now let's go ahead and create credentials. You click that button right here, it's going to take you here. You're going to say create credentials, and the one we're looking for is the Oauth client ID. They have some options here, but this is the one that we want. For the application type, we're just going to say it's a web application. I'll leave the web client. You can change that if you want to, and then we want to add our authorized redirect. It's going to be http localhost auth Google callback, and that should be fine. Let's try it and see, and so now you see we have some credentials here. It's given us a client ID and our secret. Okay, we'll add the client ID here and the secret. Now we can go ahead. Some options here, you can also download the Json version and just click OK, and these are also available anytime that you want to come back and you need those credentials again. You can come right in here. You see that the client ID is up here, and the client secrets here, and it also gives you the date when it was created. Let's head over to the Laravel documentation and see what else we could need. We're back to our routing, so we need to add these functions to the routes that we created so let's go ahead. I'm going to copy all of this. We're not going to use all of it but just to have it as a reference. From here, we're going to go to the social controller that we created. I'm just going to paste those in. Okay, so the first one, we're going to have a public function and this one we're going to call it redirect because that's what we named it in our web route, and then for this one we're just going to return this, and I'll copy this one for the next one because we'll do the same thing. This one will just be callback, and then we just need this. This is going to be the Socialite user. Go ahead paste that. The only thing that I want to do right now is just to die and dump that user just so we can see what we're getting. Because we are trying to use these two routes for multiple providers, we're passing in the provider into those routes. Okay, we're passing in the provider to both of these routes and we have GitHub, GitLab, and Google. Instead of adding all of these to additional routes, we'll just use the provider that we're injecting in here. Means that here now we can do provider, and instead of the driver being GitHub say that it's provider. That means, no matter which provider we're using, that's what's going to be injected into these routes. Let's also go ahead and import Socialite. Let's go ahead and try to click a button and see what happens. Okay, we'll go ahead and start with the easy one which is GitHub. We'll go ahead and click that. That button that we clicked was the redirect. It has redirected us to the GitHub authorization, and now you can see if you want to use this account, it tells you what it's using and all it's doing is just using our email and it gives you some other information here and this is basically what it'll be redirected to. So, let's go ahead and try to click that and see. Okay, we're being redirected so now we should be redirected to our callback function which is right here. As you can see we have a nickname, we have an email, Avatar. We're not going to use an avatar, but if you click this here, you can see we have some other information too. So an ID number and this is our ID for GitHub, and we also have a token and what I want to do is, I want to store some of this information in our database so that when the user logs in we can recognize that user and have some information about them in our project. Not all information, just some information. Fantastic! What are some of the things that we can use to do that? Well one way that we can do it is have a database, right? And the database will be something like, I don't know we'll call it socials. Which means that we can also give some sort of a relationship to the user. Whether or not they're authenticated doesn't really matter. We're going to sort all of that out, but what that entails is really having a migration and a model. So let's go ahead and take care of that. So what can we do? We'll do Sail artisan make, we'll do the model and we'll call it social, and this way the relationship to that user will be their socials. Okay, so we'll do socials and we'll also make a migration for that, and that should be good to go. So now we can close that and let's go ahead and get started with the migrations. So it should be socials. Fantastic! The first thing that I want to do is, I want to set up a foreign ID. We're going to have the user ID be the key, and we're also going to want this to be nullable. If a user has created an account with a password and everything, then they don't necessarily have to also have a social. But in the off chance that they do, then we can associate that user with the ID. So this is something that can happen as well, and even if they just registered or logged in or authenticated with their socials, then we'll create a user. Okay, and this will be their user ID. So either way it works for us. I also want to make this constrained and I also want to cascade on delete. Okay, let's take a look at what we're getting. The other thing that we're getting from here as well is the -- This Id is a provider id so we can call it provider id, we're also getting where it's coming from, so let's try this real quick. In our social controller, I want to instead of returning the user, I want to return the provider, like this. Okay, so let's try this again and see what we're getting for the provider. I'll try GitHub again as you can see we didn't have to be redirected back and forth again. This is now an authenticated user that we have already acknowledged within our system. It has already been acknowledged by our application, so the first one we have is GitHub and that's the provider, and the same thing will happen with GitLab and the same thing will happen with Google and then you know we have our user down here. Great! These are things that we want to add to our table. After the ID, I want to do a string and this we're going to do provider because we're already getting that. We can have that and this is something that we'll also want to make nullable. Then we also want the provider id, which we're getting from that Socialite user as well. So this will be a string. Then we're going to do nullable, and then we're also going to need the token and the refresh token. Now, not all of them will have this refresh token, so again that's something that we'll want to leave nullable. Let's go ahead and now bring this also to our model, and we'll make those fillable fields. If you're not sure why I'm doing fillables, some people will do guard some people will do -- or guarded, some people will do fillable. Now I like to make sure that I know exactly what it is I'm filling it in. Sometimes it might be months before I come back to a project. This is just my personal preference. If you're going to do guarded, then you will not need to add all of these. It would be something like this. Guarded equals an empty array. If you do this, then you need to make sure that you specify in your controller or what have you, to know exactly what fields you're going to be allowing in, because it just they are the opposite. For fillable, it is specifying exactly what can be filled in and if you're doing guarded it will specify absolutely nothing of what you can let in. So just be mindful of which ones you're using. For me, I'm going to use fillable. I'm also going to create a relationship here and this one will be belongs to. This is saying that the social belongs to the user. That's how these are read. Okay, we'll make sure that that's imported up top. I believe I did it here, and we don't need these foreign keys or other keys. Okay, let's go ahead and create the relationship with the user as well. So the relationship that I want to do is has many, because a user can have many different socials, which means that if they decide that they want to instead of log in with GitHub, they can also log in with GitLab. That means that that user ID will be that specific user ID. So has many, and we'll say socials because a user has many socials. That's how this one is read. Let's go ahead and import that, and we'll get rid of these keys. We need to change the model from comment to social. Now that we have that, I want to migrate this table because I will absolutely forget to do this later, and we'll have to come back and correct it then. So for now, we'll just go ahead and run the migration. Fantastic! So our socials table has been migrated. Let's close some of these out, we can close the table, models. Okay, great. Our redirect is pretty much done. We just need to work on this functionality. What are the things that we're looking for this user to authenticate them for our project? Well, the first thing that I would look for is to check to see if the user already exists. If the user doesn't exist, then what do we want to do? We want to create the user, and then we want to create the socials for that user if the user doesn't exist. Well, first let's do this. Let's do, if doesn't exist then we'll create the user and create the social. If the user does exist in our project, we're already checking to make sure that they check if the user exists right? If they don't exist, then what we can do is add socials to user. Well, first we want to check if user has socials and then doesn't have socials, and then if they don't then we add socials to user and then those are the checks that we're going to make. After that, we're going to log in the user and then we're going to redirect them to the app. So again, let's take a quick walk through. We're going to check if the user exists. If they don't exist, we're going to create them, and then we're also going to create socials. If they do exist, then we're going to check if that user doesn't have any socials, or doesn't have the particular social that we are trying to use. Let's say they are already in our project, they already have an authentication with let's say GitHub, but now they want to log in with GitLab. Okay, then we'll add that GitLab to that user's account, and then after that we'll just log in, and then we'll redirect them to the app. Let's go ahead and really kind of get started in this. We're going to check if the user already exists right? Instead of this being user, we'll call this one social user, and then we're going to say a user equals user, because that means that they're already in our database. So we just want to check if the user is in our database. Checking if the email of that user belongs to the social user, and then Socialite gives us these nice little functions so we can use get email, and then we're just going to be looking for the first one. This is the user that we're looking for. We're using the models. Okay, so this is the user in our database, and this is the user that is trying to authenticate with whatever the provider is. So we're checking if this user is already in our database, and we're calling this one user, and we're going to be looking for the user where the email is the social user. We're just checking if that's first. So we'll leave that there. If it doesn't exist, so if no user then our user will equal user create. Okay, so they are not in our database exclamation point there, so user create. What do we need? We need a name. We could say Socialite user name but what I want to do is, I want to make a new variable because not all of the providers that user will have a name. They'll only have a nickname, and I don't really want to use a nickname for user if they already have a name. Okay, so what I want to do is, I want to do name equals social user get nickname, or going to do social user get name. So if they only have a nickname and no name then that will be what's injected into our user's name field. If they have a name, then that's what will be injected into our user's name field. So here, I'm just going to put name so that we can have a value for that. Then I want to do the email and we'll do social user get email. Now something that we will also need, because if we take a look at the users table, the password is actually mandatory. We don't have anything saying that it's nullable here. Instead of making it nullable and just putting passwords at risk, we can just create a new password for this user. Just a random password, and then if they decide that they want to log in with the username and password, then they can change their password. We'll say password equals, want to do hash make, and then I just want to do string random and just leave that at seven. And again, they'll be able to change this if they want to or not. They're not obligated to use that same password, but that's something that you know they need to decide on there end. Either way, we're going to have our password field filled in. Then after that user is created, now we can use that relationship, so a user socials create and then it'll be provider id, and that will equal the social user get ID. That's another function that we have, and then the provider we'll just say that that equals provider because we're already passing that in up here. Then we'll need the token, and that will just equal social user token. There's no function for that, and then the provider refresh token equals social user provider refresh token, and that doesn't have a function either. This one we can move up. User create socials for the user. This is if the user does not exist. If the user does not exist, we're going to check if user doesn't have socials. What we can do here is socials equal social, because we have that model, where the provider equals the provider that we're passing in, and we can also do where user ID equals the user ID first. Again, this user ID is coming from up here, this user. Now that we have that, we're going to check if no socials, which means that they don't have the relationship with this particular provider that we're passing in. Then we can go ahead and add that, so we'll say user socials create and actually I can use the same thing, and then we'll move this up because that's done, and then we can go ahead and log in the user and I want to move over a bit. Here now we can do auth login. That's just the Laravel method for logging in a user, and then we need to also pass in the user, and then we can redirect. The route that we would use to log in that user, whether or not they're in our system, when we have a regular authentication we just return redirect and we'll just say dashboard because that's what happens with an authenticated user anyway. They just get redirected to the dashboard. So I think we have everything pretty much set. Again to walk through, we're checking if the user equals a social user, meaning they're in the system. If they're not, then we're going to create them, add the socials. If the user does exist, but they do not have our socials then we are going to go ahead and attach those socials to that user. Even if they have GitHub or something like that and they add another one, then they can you know this will be added. Okay, well let's go ahead and give this a try. I'm going to go back, I'm going to refresh that, and then we're going to go ahead and try it with GitHub. As you can see, we have been redirected to the dashboard. We are logged in. Here is our name. We can also take a look at our profile, and as you can see we have a name, an email, and if you had set up the profile photos you could also use Avatar that we can also grab from there. I didn't do that for this, but you can use that as well and we have everything available that's for the user. Let's go ahead and try another one. We're going to log out of this one. Let's try to register with the GitLab. I want to use this one. This is the nikosdummy6, and again we have been redirected, and if we take a look we have our name and this is the same information that we had with GitHub. Let's go ahead and take a look at the database as well. Okay, and if I go ahead and open up the users, you can see we have one user with our name our email. This is the password that we put in, and you know it just has the same information which is fine, but I want to take a look at our socials table. Okay, and if you take a look, as you can see we have the user ID and we have the user ID of one which is the same user. You can see we have two different providers, one is GitHub one is Google. We have our provider IDs for each, and we have the provider token, and again these refresh tokens are null but we have all that other information as well. I want to also try the Google one. Okay, so we'll go ahead and log out of this one, and we can go ahead and register, and again we're using the same functionality for register and login so it's going to be the same. As a matter of fact, if we go ahead and try to go back to that login route, and we try the Google. Sorry I think we tried this one already, we need to try the GitLab. That was the last one, sorry. Okay, go ahead click that one. Well actually, actually I want to show you from the login page, so we'll go to the login page and go ahead click GitLab, and as you can see it's the same thing. Do you want to authorize the Socialite with your account? This is what it's telling you it's going to do and do you want to authorize? We're going to say yes. Okay, very good. We have been redirected to the dashboard, and let's take a look here and the exact same information. If we take a look at the database and go ahead and refresh this, you see now we have same user ID. GitHub, Google, GitLab and then we have all of the other information for that, and we haven't created any new users. Now keep in mind, we have used the exact same email for all of them, which was how we were able to have multiple providers for the same user. We are identifying them by their email. If you have, let's say another GitHub account, so let me log into the other one. Okay, as you can see I am logged into my regular GitHub that you guys all know, which is designated coder. This is where I have all my repos, and also the repo for this demo will be in here as well so just check the description down below for that. But what I want to do is, now that I'm logged in as this user, I will have a different email. So if we go ahead and log out, I'm going to try to log in with that new user. Register, GitHub. So as you can see this is now a different account. Okay, so Socialite wants to access your designated coder account. Let's go ahead and authorize it, and as you can see we are now logged in as a different user. Even though I'm the same user with two different accounts, we are logged in with this new email address. Let's go and take a look at the database. Go ahead and refresh this. Now we have the second GitHub account. If we go to the users now, you see we have two separate user accounts, and I can't access my login with those accounts. Now if you want to implement something like this, to give you some idea of what you could do to have this kind of a situation be for the same you know for the same account is maybe create something on the front end where you ask them do you already have an account? and with what email? and something to that effect in your front end? But that is another thing that you can consider. I would have something like that for your front end because I think that would be a pretty cool way to do it, but as of now this is the same thing that you would have with pretty much any sort of social media account that you would have. You would have your account set up with that email you know. When you log into Facebook, you can't see all your other Facebook accounts or however it works. If you know what I mean, you can't see all of them at once. You're logged in as that particular email. Keep that in mind when you're doing this and hopefully if that's something that you want to do you can do that as well, but as of now we've managed to set up Socialite. Something that we don't have set up is, let's say you go to register right? I'm going to log back in. Okay, if I go to the settings again and we access our project developer settings, Oauth apps. Okay, this is the project that we have, as you can see we have two users so what I want to do is I want to revoke. I want to revoke this and then I'm going to refresh, and I'm also going to re-migrate our table. I keep forgetting I'm using Sail. Sail artisan. Okay, great. So I've re-migrated this. I want to show you something. I'm just going to go ahead and refresh this. We're going to go ahead to GitHub. So it wants to access my nikosdummy, right? Let's say I want to cancel out of this, and not authorize it. So we're getting this weird client error. It's a 401 error, basically. [401 => 'Unauthorized'] So I want to basically throw an exception and return the user back to the login page. The easiest way to do this is to have a try catch, and instead of the socialite user being down here, we're going to put it up here, and we're going to try to hit that callback record and see if we can get this user before anything. In the event that we can't do that, so like we just did we want to cancel out, what I want to do is I just want to return redirect, and we'll just say route login and that should be good. Let's try it again. That's all I want to do is, I just want to make sure that we get redirected back somewhere instead of just having that weird error. So we'll go ahead and do cancel. Okay, look it's trying to redirect. Okay, and now we are back on the login page as intended. If you're enjoying the content, please go ahead and click that like button because it really does help out the channel. Here's a video YouTube thinks you'll like, and here's a playlist to follow along. Thanks for watching. I'll see you next time.
Info
Channel: Designated Coder
Views: 1,287
Rating: undefined out of 5
Keywords: laravel, laravel 8, designated coder, #dezignatedcoder, designatedcoder, laravel 9, laravel 10, laravel socialite, laravel socialite google, laravel socialite github, laravel socialite gitlab, laravel social login
Id: jC4TkgxPjVU
Channel Id: undefined
Length: 39min 30sec (2370 seconds)
Published: Thu Jan 12 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.