Web Authentication APIs Registering & Authorizing
Transcript from the "Registering & Authorizing" Lesson
>> So now that we have the endpoints, maybe the next step is to add this endpoint to APIJS, we can continue with a copy and paste because it's actually most of them are actually pretty similar. So I'm going to copy and paste that within APIJS, like maybe here, in this case, I did a whole object for all the endpoints just to group them on webAuthn.
[00:00:25] So we have loginOptions, loginVerification, registrationOptions, registrationVerification. And on verification, we are going to send the email and the data that we received from the API from the webAuthn API, that's the one that's going to be verified. And if everything is correct is the one that we save in the backend, Okay, makes sense?
[00:00:51] So from an API endpoint point of view, we are done. But we still need to understand how or when are we going to integrate this into our PWA, our Web App, our authentication flow. So, one idea, it's not the only idea, it's one idea, is that when we are logging in a user that, or after we log in, let me log in with Google.
[00:01:21] Here, we can add a button that after we login for the first time or any time, we can go on add a new authentication or passkey or face ID or touch ID. So that's one way. So we register a webAuthn process in this page, in the account page, does it makes sense?
[00:01:46] And then after we login, so if I log out here, when I log in when I continue while this is wrong, some reason firstname.lastname@example.org on the next step if this user has face ID, I can show here a button or an icon or something that says instead of the password or along with the password login with face ID.
[00:02:15] So, before actually doing that, let me give you the bad news. The bad news is that the API is authenticator agnostic. So it accepts many authenticators, it can be a platform authenticator, Face ID, Touch ID, Windows Hello, or it can be an external authenticator. But you don't know which one the user has used, and you don't know which one is available.
[00:02:44] I mean, you can check something in the API, but you will know if face is available, okay? Or fingerprint is available to render like a nice button saying touch or face. So to do that, unfortunately, you need to do today at least some kind of user agent by the device validation, okay?
[00:03:09] If it's an iPhone which iPhone well in this has face ID so then you use a face ID button, if it's a Mac you use Touch ID and if it's Chrome you can decide what to do because it's multi system okay? So I mean if you want to be like integrate it with OS you need to get into conditionals based on the OS based on the browser and so on.
[00:03:36] So if you want to be multi platform which has asked for web authentication, or the whole community is going towards a name passkey. So, you will add a passkey, that's the noun, that we are using for a way to log in in a website no matter how you are going to create the passkey, okay?
[00:04:02] Make sense? Okay, so going back to the code, let me make it work. So I'm going to index.html first, so let's add the buttons or the button first to register. So I'm going to the account section. So I have a page here for the account and before the logout or after, whatever you want, we are going to add a button here that onclick I'm going to call Auth, it can be register, passkey or addWebAuthentication, whatever name you want.
[00:04:40] And again, here we can say they want to add a new authenticator, a new passkey, the UX for this, I think, it's still in discussion, which is the final UX that everyone is going to use. I think at the end it will depend on what the big players are going to do in the future, because users will recognize for that user experience, okay?
[00:05:07] Make sense? Can you assume so far? Nope. So now we need to make that addWebAuthn method. So another one you wait as long as this point, so, addWebAuthn is going to do something and it's going to be async because the whole WebAuthn API is asynchronous, so let's start with async.
[00:05:37] So the first step, remember, the first step is to go to the server and request the challenge and the options. So, we need to first get the options from the API. So webAuthn.registrationOptions. So we wait for the server to send me all that information and here is where we are going to call so we are going to take a response from the webAuthn.
[00:06:12] I'm leaving a space, because I will add some options there. So we're going to wait and we're going to call the SimpleWebAuthnBrowser library, the problem is that this is a library that I need to import first, okay? So, well, let me write the code and then we import that.
[00:06:32] So we're going to startRegistration and registration need options,okay? Those are the options that we have here, but client side, we can also add more metadata to that option, okay? So for example, we can define the authenticatorSelection.residentKey as required. So this is actually gonna be useful for passkeys. Okay, I will explain that later.
[00:07:09] And the same as authenticatorSelection.requireResideKey you have the code to copy and paste in case you want to. And extensions, credProps, you know what is that? Okay, we'll see in a minute. Okay, here's a JSON so nothing like that. Okay, so once we have the registration remember this isn't going to work if we don't add the client side library to our HTML.
[00:07:42] But when we have the registration, the next step is to send this object back to the server to verify. Remember the two steps process for WebAuthn? So first we ask the server for options, then we call the authenticator to do the stuff with the Face ID or wherever.
[00:08:02] The authenticator will give me a response, and then we need to send back that response to our back end to be verified. So now we are going to wait for another response for another API that is registration verification and verification will need the response that we have just got from the web API from the previous line, okay?
[00:08:33] And here we check if verification is okay. So if the server is give me, okay, I can make a message or something say, You can now login with WebAuthn. If not, it didn't work, so we could maybe show the message that the server is sending in case we have one, something like this.
[00:09:00] So, this is the one that is, in fact, this code that you see here, is the one that is explaining this flow that we saw before, this one. It doesn't matter if you see the flow again, but it's that flow, that two-step flow, we go twice to the server.
[00:09:18] So I'm going to the server here and then I'm going to do a server here, that's why we have two endpoints. But this is not going to work because I need to add this library. So it's time to go for the first time to the website for this library that is .dev, the name of the library .dev.
[00:09:37] Actually, the documentation, it's good, good, I'm not sure it's good enough, it's good enough minus one, it's okay. They have an example that is tricky to follow but it's compared with the other libraries available for authentication this one is the best one for sure okay? The other one's even worse than than this one.
[00:10:00] So it's that simple to use first class type of support in fact the sample available in the repo is TypeScript, okay? So, I mean, if you are happy with TypeScript, that's fine. And when you go to the docs, here you can see the packages and everything, and there is a whole section on passkeys, for example.
[00:10:22] So it's actually pretty updated, talking about iOS 16, the Ventura, Microsoft Ventura so they are behind the library. The other libraries I kind of have a little behind okay, compared with this one here you have all the habits with Android that I will explain what happens with Android in a minute.
[00:10:44] So you have here what happens with Safari browser, what happens with Edge browser. So they are following compatibility on each browser that's why I think it's pretty good. And when we go to the packages for the browser, here we have how to install this from NPM or to copy and paste the script from a CDN.
[00:11:05] So we can just copy and paste it from a CDN because we don't have packager we're not using any packager for the front end, so I just need to add this here like so. So now we are ready to use the client side library. These client side libraries, shares calling webAuthn client side.
[00:11:28] Remember that webAuthn, it's exactly sitting on top of credential management API. So it's saving the private and public keys in Credential Management using Credential Management API, okay? Well, I think that we are ready to try this let's see what happens. So I can log in with Google or with password, it should work with both.
[00:11:59] So now I have this Add Authenticator/Passkey, okay? So let's see if that works, if I click there, voila, we have first that dialogue that's a Chrome dialogue saying, okay, how do you wanna save an authentication? Using a USB security key, let's write the USB key first. So I'm going to connect this USB-C, so I'm going to connect this to my computer.
[00:12:26] Okay, it's connected, so USB key and then I need to touch it because it needs interaction, so I need to touch it and then in this case a pin is required, so there will be a pin on top of that 1, 1, 1, 1. Next, incorrect pin this is the pin for my security key interesting because I didn't remember they had a creaky, okay it worked.
[00:12:53] And now I need you touch again. And now I can login with WebAuthn, did it work? Well, the process seemed to work, let's see the database. So we'll look at the database so I will open, here I have my JSON. So now Look at this, this is Maximiliano Firtman Google federated Google account.
[00:13:15] And I have here while this was the challenge, I have devices, it's an array of 1, with a buffer. So that's the public key with some other information that here it says that this was used through USB and NFC. So, based on these values, you could read that metadata and show the user a message saying that, or you can, no this is a USB key and not Touch ID, okay?
[00:13:50] Let's write Touch ID so I'm going to add another one. Can I add more than one? Yes, in my endpoint it will work so I will add another one, I will say this device, and I will use my finger you can now log in. Okay, let's see now here, I have another object with another buffer array that says, internal, so, in this case, it was an internal authenticator.
[00:14:20] Again, do I know if it's touch or face? No, but because it was a Mac, I can say, yeah, it was touch ID, so next time, I could say to the user hey, you wanna use touch ID to log in? Any question at this point? Well on Safari, it should work in Safari as well.
[00:14:43] Do I have it loaded? No. So local health 50/50 again. 50/50, let's use the other user, email@example.com and the password was Frontendmaster I think. You want to save it? Well, okay, save it. Let's add authenticator, this is how Safari render things by default, it goes automatically to Touch ID or Face ID.
[00:15:12] But also I have other options, in other options, I can say that I can use iPhone, iPad or Android, as my authenticator or a USB key or I can create a passkey. You can see that the passkey in Ventura is kind of the wording for Webauthn, I can save a passkey in the iCloud keychain that will be synced across Apple devices.
[00:15:37] So it's not just this device. So I will continue with Touch ID, done. Okay, you can now log in. So going back to our app, if I look here, my m@m here is it has an internal hybrid, that's how Safari identifies its authenticator with an array buffer. So, the registration flow is working, I'm still missing the part where we are actually making the authentication, the login, okay?
[00:16:17] But do you have any question at this point on this? No? And by the way, we were saving a true, WebAuthn true here. So that means that even if the login process is not ready yet, if I open the Network tab and I'm currently logged in as Maximiliano let me logout first, login again as m@m.
[00:16:45] Continue, the options will tell me that I can log in with password or with WebAuthn, makes sense, right? Because now we have a device registered, at least one, registered in our database.