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

feat: added optional userHandle field to authentication response #41

Merged

Conversation

asgarovf
Copy link
Contributor

@asgarovf asgarovf commented Mar 9, 2024

What

The authentication response does not contain the optional userHandle field.

Why

The original AssertionResponse object also contains userHandle field based on Webauthn spec. According to docs:

The authenticator MUST always return a userHandle if the allowCredentials option used in the authentication ceremony is empty, and MAY return one otherwise. However, in the current library the userHandle is never returned. userHandle field returns the userId provided in registration if the credential is discoverable (otherwise it is null) and we might need this value while authentication.

How

Add optional userHandle field to AuthenticationEncoded type and authentication response of webauthn client.

@dagnelies
Copy link
Collaborator

dagnelies commented Mar 9, 2024

userHandle field returns the userId provided in registration if the credential is discoverable (otherwise it is null) and we might need this value while authentication.

Using this library, you can explicitly set it like that:

const registration = await client.register("MyUsername", challenge, {
  userHandle: "..."
})

The "user handle" is actually the "user id" during registration, it's just really confusing in the specs. In other words, you already know the handle when registering. This lib sets it for you and as far as I know, you actually never need it afterwards, so it isn't returned. Authentication does not need it, whether the credential is discoverable or not.

As far as I know, the only usage (which is not really in the spec) is to use this user handle to override an existing credential/passkey with a new one for that user/device (for example to change the display name). But that's already fairly advanced. Or is there something that I missed?

If it's useless, I would tend not to return it.

@asgarovf
Copy link
Contributor Author

userHandle field returns the userId provided in registration if the credential is discoverable (otherwise it is null) and we might need this value while authentication.

Using this library, you can explicitly set it like that:

const registration = await client.register("MyUsername", challenge, {
  userHandle: "..."
})

The "user handle" is actually the "user id" during registration, it's just really confusing in the specs. In other words, you already know the handle when registering. This lib sets it for you and as far as I know, you actually never need it afterwards, so it isn't returned. Authentication does not need it, whether the credential is discoverable or not.

As far as I know, the only usage (which is not really in the spec) is to use this user handle to override an existing credential/passkey with a new one for that user/device (for example to change the display name). But that's already fairly advanced. Or is there something that I missed?

If it's useless, I would tend not to return it.

For example, in our use case we set the user id as public blockchain address to identify users. We need to get the returned userHandle (which is user id during registration ) value to query user in blockchain or in our db. Please refer to the flow below. We have overridden this function internally to make it work.

clave-auth

@dagnelies
Copy link
Collaborator

Aha... I missed the fact that the spec now says the userHandle should be returned during authentication. A year ago, it wasn't the case, and no authenticator returned it. I wonder how the situation is "in practice" by now. I'll take a closer look at this PR soon and expect it to be merged once docs and examples are updated.

@asgarovf
Copy link
Contributor Author

Aha... I missed the fact that the spec now says the userHandle should be returned during authentication. A year ago, it wasn't the case, and no authenticator returned it. I wonder how the situation is "in practice" by now. I'll take a closer look at this PR soon and expect it to be merged once docs and examples are updated.

Sure, I will update the docs!

@dagnelies
Copy link
Collaborator

This webauthn protocol is really in constant evolution, with sometimes fundamental changes like synced keys instead of device-bound and browser behaviors that change each season.

...long ago this userHandle was a useless piece of junk ...now that it's returned during authentication, I wonder if renaming it into userId would be more sensible. In other words, going back to the original user:{id,name,displayName} and deprecate deprecate userHandle altogether. But let's leave that for "v2". ;)

@dagnelies dagnelies merged commit efed234 into passwordless-id:main Mar 11, 2024
@dagnelies
Copy link
Collaborator

should appear soon in v1.5.0

@asgarovf
Copy link
Contributor Author

should appear soon in v1.5.0

Thanks! Agree on renaming to userId for simplicity in the future.

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

Successfully merging this pull request may close these issues.

None yet

2 participants