در حال بارگذاری ...

Series Introduction0:00

I think I know who you are. I think you're somebody who has been following the Passkey story, you really like the idea of them and perhaps you're even using them in your Apple or Google or Microsoft account, and you'd like to bring that experience over to your Laravel app, but the last time you checked, it just blew your mind. And you know what? You're not to blame. Passkeys are complicated. But I've spent the last few months researching them, boiling it down to its bare minimum in order to be able to show you how to integrate them into your Laravel apps.

Clone Starter Repository0:26

But I've spent the last few months researching them, boiling it down to its bare minimum in order to be able to show you how to integrate them into your Laravel apps. So if you follow along with this series, you're going to learn pretty much everything you need to know to take that learning away and apply it in your own applications to give your users an awesome authentication experience. Let's dive in. I would really recommend that you go ahead and clone the linked repository, adding Passkeys to your Laravel app, so that you can code along with me as we add Passkey integration, because you'll learn so much more by doing so. Essentially it's a Laravel Breeze app built on Blade with AlpineJS.

because you'll learn so much more by doing so. Essentially it's a Laravel Breeze app built on Blade with AlpineJS. I've gone for the simplest possible stack so that you can take the learnings into any of the other more complex stacks. And the only real difference is that in the profile page, I've already added this little UI for managing Passkeys. It's not wired up. It doesn't actually do anything, but it just means we're not going to be spending time writing HTML. So go ahead, clone the repository, and then continue the video.

Create Passkey Model1:32

writing HTML. So go ahead, clone the repository, and then continue the video. We're going to begin our journey by creating the database structure needed to support Passkeys. So we'll start with our model, php artisan make:model Passkey. And although technically what we're going to be storing is a public key credential, I'm going to call it a Passkey, because it's just so much easier to remember. And essentially, that is what we're integrating. So I'm going to name the model Passkey. And let's grab a factory, we could have a migration and a policy. And why not?

Design Passkeys Migration2:03

And let's grab a factory, we could have a migration and a policy. And why not? Let's have a resource controller as well. We'll start with our Passkeys migration. So along with the default ID and timestamp columns, we're going to add a foreign ID for the User model, because a User has many Passkeys. So User class, we can constrain the relationship. And just to make it clear, I'll use a cascade on delete relationship here. We should also provide a way for the User to have a friendly name for Passkeys, seen as they can have multiple Passkeys stored against their account.

We should also provide a way for the user to have a friendly name for Passkeys, seen as they can have multiple Passkeys stored against their account. And they'll want to know which is which. So we'll store that in a simple text field. Our other fields are related to storing information about the Passkey itself. So the first thing we need to store is the credential ID. That is an identifier that we can use to find the Passkey again, when the user tries to sign in. We can use a nice simple text field for this as well. So credential_id.

Add Relationships and Factory2:59

We can use a nice simple text field for this as well. So credential_id. And then finally, we want a json column, which is going to store any data associated with the Passkey that we'll need to use to reconstruct it from the server. So this is all you actually need to store information about Passkeys in your app. Let's go ahead and fill out the model. As we mentioned, a Passkey belongs to a User. So let's be sure to create that relationship on the Passkey model. And on the User model, well, we'll want the opposite. We'll want a Passkeys hasMany relationship.

And on the User model, well, we'll want the opposite. We'll want a Passkeys hasMany relationship. I can use Laravel Idea to make things a little bit easier for me here. There we go. That's the relation set up on both sides. We also have the Passkey factory to fill out so that we can create fake Passkeys. We'll start with the name attribute, which we can just set to a fake word for now. Then we have the credentialID. For this, I'll just use str_random. data is going to be an empty array.

For this, I'll just use string random. Data is going to be an empty array. And again, we'll talk more about that a little further down the line. And then obviously we have our userId, which we can set by default to an instance of a UserFactory. And there we go. The columns for our PasskeyFactory are filled out. Finally, let's update our DatabaseSeeder so that we can give our default User some Passkeys out of the box. So let's say that this UserFactory has, and we'll say PasskeyFactory.

out of the box. So let's say that this UserFactory has, and we'll say PasskeyFactory. Maybe we give them three Passkeys to get started. Let's go ahead and reseed our database. We're getting an exception because we have an array to string conversion. Essentially in the PasskeyFactory, yeah, we're assuming data is json, but we've not actually specified anything on the model itself. So we'll go back into Passkeys here. And for now, I think I'm just going to create a casts method where I set data equal to a json column.

Render Passkeys in UI4:50

And for now, I think I'm just going to create a casts method where I set data equal to a json column. Down the line, we're going to have to make adjustments to this. But for now, that will work absolutely fine. We can now go ahead and migrate fresh with seeding. And if we come back to our front end, we should now be able to update this your Passkey section to use data from our database rather than the hard coded values that are here currently. So let's open up our managePasskeys.blade.php file. And underneath the your Passkey section, we'll wrap the list item here in a forEach. We can say $userPasskeys as $passkey.

And underneath the your Passkey section, we'll wrap the list item here in a foreach. We can say User Passkeys as Passkey. And then we'll obviously make sure that the closing tag goes after the list item at end for foreach. Nice. And we can update one password here with Passkey name. We have the created_at timestamp for this. So let's go ahead and use something like Passkey::created_at. And then do we have diffForHumans available in Carbon? I'm pretty sure we do.

And then do we have diff for humans available in Carbon? I'm pretty sure we do. So let's go ahead and try that. Is that everything? I think that might be good. Let's take a look. So back to the front end, refresh. And yes, it is. So here is your Passkeys. And you can see we're pulling three Passkeys from the back end for this User, exactly as

Homework: Wire Delete CRUD6:06

So here is your Passkeys. And you can see we're pulling three Passkeys from the back end for this user, exactly as we'd expect. So that's our database set up complete. I have a little bit of homework before you move on to the next episode just to get your developer brain moving. And that is, I want you to go ahead and wire up the CRUD for the remove buttons on the your Passkey section. We already created the Passkey controller and there is a destroy method available. So create the route that links to it, wire it up, call Passkey::delete.

We already created the PasskeyController and there is a destroy method available. So create the route that links to it, wire it up, call Passkey::delete. And for bonus points, go ahead and fill out the policy as well to make sure that you can't delete somebody else's Passkeys. Once you've done that, I'll see you in the next episode.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟