Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow passing authenticatorSelection.residentKey option in client.register #34

Closed
Ionaru opened this issue Oct 1, 2023 · 9 comments
Closed

Comments

@Ionaru
Copy link

Ionaru commented Oct 1, 2023

Which problem is this feature request solving?
In my login flow, I do not want the user to have to type a username. So I pass an empty array of credentialIds to client.authenticate. This unfortunately does not work in this library because the created passkeys are not a "Client-side discoverable Credential". To create "Client-side discoverable Credentials", the residentKey option in authenticatorSelection during registration needs to be set to "preferred" or "required".

Currently it is not possible to set the authenticatorSelection.residentKey option in client.register

This login flow is also mentioned in your README.md, but as far as I'm aware, not currently possible to create with this library.

Describe the solution you'd like
A new option in the third parameter of client.register (RegisterOptions) for residentKey, to set a value for authenticatorSelection.residentKey in creationOptions.

Describe alternatives you've considered
Maybe a generic override using a Partial<PublicKeyCredentialCreationOptions> interface would be preferred, this way any option can be changed without needing a code change every time someone wants a new option to be supported.

Can you submit a pull request?
Yes, if the feature is approved.

@dagnelies
Copy link
Collaborator

dagnelies commented Oct 2, 2023

Hi...

In my login flow, I do not want the user to have to type a username. So I pass an empty array of credentialIds to client.authenticate. This unfortunately does not work in this library...

This came to quite a surprise for me, so I tested again and ...It currently works for Windows (popping up native user selection) but not in Android (saying no passkey available)... damn protocol.

...because ... the residentKey option in authenticatorSelection during registration needs to be set to "preferred" or "required".

Are you certain it's related to this attribute? It would be nice to test on all platforms to obtain a homogenous behavior.

Maybe a generic override using a Partial interface would be preferred, this way any option can be changed without needing a code change every time someone wants a new option to be supported.

...that might be an option ...let me gather my thoughts and sleep over it.

@dagnelies
Copy link
Collaborator

dagnelies commented Oct 2, 2023

PS: That's also a case where residentKey and requireResidentKey should be set in sync and perhaps rename it into discoverable or so to be more intuitive

@Ionaru
Copy link
Author

Ionaru commented Oct 3, 2023

Thank you for the quick reply!

It currently works for Windows but not in Android

That would match my observations, I tested on Android and the chrome devtools.

That's also a case where residentKey and requireResidentKey should be set in sync and perhaps rename it into discoverable or so to be more intuitive

I think that would work.

@dagnelies
Copy link
Collaborator

Added "discoverable" in version 1.3.0. Confirmation that it works as expected is welcome, See playground

@Ionaru
Copy link
Author

Ionaru commented Oct 5, 2023

I can confirm that, in my testing application, this works as I had expected! 👍

The playground gives me a "credentialId mismatch" error, but it also allows me to choose from my previously created accounts as I wanted.

Thank you so much for the quick implementation of this feature!

@dagnelies
Copy link
Collaborator

dagnelies commented Oct 5, 2023

If you create both a discoverable key and a non-discoverable key, both will coexist, even with the same userHandle / user ID. (That was new to me, I thought they would override each other, but I guess being synced or device bound makes it two distinct credentials)

I guess the mismatch occurs when you register a non-discoverable key, then try to authenticate with an empty list which will deliver the other discoverable key.

@asbjornenge
Copy link

@Ionaru hi there! I am also trying to use this library without usernames 😅

  1. When doing register do you simply pass a randomly generated string as the username? Or an empty string?

  2. When trying to decide between calling register or authenticate for a login attempt, seems I need to know if the user has previously registered a key for the site. Do you cache this information in localStorage? Or is it possible to use the library to query if a key exists? 🤔

Thanks!

@Ionaru
Copy link
Author

Ionaru commented Jul 7, 2024

@asbjornenge Hello! I'll gladly answer your questions.

  1. I've settled on an optional username field that's pre-filled with a unique-ish value. Like MyAppAccount #5321. (Doesn't have to be actually unique, just unique enough so the user can identify it on their device). Then during login, the user can select the correct account to log in with.

  2. So far, I've not found a way to automatically detect whether a resident credential already exists for a domain, with this library or using the API directly. So at the moment I think we're stuck with the 2-button setup, one for Login, one for Register. I think your idea of using localStorage is really good, you can cache whether a login has happened before to make one button more prominent than the other.

For a presentation a little while ago I've built a demo/testbed application for webauthn using this library in the backend. Feel free to check it out and play around with the settings: https://github.com/Ionaru/webauthn-demo

I'm always open to new ideas to help bring this new tech to widespread use. :)

@asbjornenge
Copy link

@Ionaru thanks for your prompt reply 🙏

Yeah it does not seem to be any way to get a list without "bothering" the user 😅 Two buttons it is.

I'll take a look at your demo and let you know how my approach turns out 😊 Will try to add the UID to localstorage and prefill it if it exists 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants