-
Notifications
You must be signed in to change notification settings - Fork 180
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
New PublicKeyCredential methods for JSON (de)serialization #1703
Conversation
I apologize for the roughness of these initial drafts, this is my first time attempting to submit something substantial to the spec. @nicksteele has graciously volunteered for a bit of hand-holding as I work on this, but I look forward to your comments and suggestions as we work to make this a reality. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking this on! For starters, some comments on the high-level disposition...
Alright, I've got new types defined for everything so I'm flipping this to Ready for Review. One thing I need help with (aside from review of the IDL definitions) is figuring out the proper way to address "FATAL ERROR"s like this:
I wasn't able to intuit a solution from existing definitions. I'm also uncertain how my intended API for |
Right now the method descriptions don't quite agree with the WebIDL definitions - the descriptions say that they take in and put out JSON, which would be DOMString values, but the definitions work with JavaScript objects. We need to clarify which of the two it is - probably the latter, since there's already the I'm not sure whether WebIDL allows the overloaded signature for
These errors are because the WebIDL block is enclosed in the
|
@emlun The I'd lean toward having the method take JSON text - this would both increase symmetry with the |
The idea is that the "JSON" inputs are
Huh, so if the input is JSON then you don't need WebIDL definitions for it? I approached it as though I was writing something akin to TypeScript definitions for these methods. |
You're right - toJSON() emits Objects not Strings, so the current IDL is proper. |
In JS dev land it's easy to forget that "JSON" is actually a It seems when I mention "JSON" here in the context of this spec I'm evoking thoughts of passing |
Based on some discussion during the WG meeting today, it may be feasible to update the @kreichgauer Did I understand this correctly? Or would we still need to wrangle IDL definitions to declare this behavior? |
I've been researching if this is appropriate to do indicate with a custom WebIDL extended attribute (for example |
That's how I interpret the toJSON section of the WebIDL spec at least. I did a little digging, and Web Payments seems to want to define PaymentResponse.toJSON() The Push API is a counter example. In PushSubscription.toJSON() it defines a separate PushSubscriptionJSON dictionary. But it defines its own processing rules. |
@emlun Thank you for the verbiage tweaks! Those are all incorporated now, one step closer to landing this thing 💪 |
This is already a great step forward. As far as I understand, it is converting all ArrayBuffer objects into base64url. I wonder if it would make sense to add some more nuanced conversions. In particular, I would view 2 exceptions:
Basically, it would be nice to distinguish between ArrayBuffer objects containing plain strings and ones containing data. |
Speaking to this one, the |
@dwaite I'm aware of that. I was indeed referring to a raw JSON String, not the parsed object. I think it would be rather trivial to utf-8 encode it on the server side (instead of base64 decoding it) to get the correct byte array for signature verification. It just makes things more readable IMHO. |
Unicode normalization forms would be the issue here, not utf-8 encoding (I would expect the JSON to already be UTF-8 encoded). The only way this works AFAIK would be if the client and the server (either through normalization step or intermediary transport guarantees) represented that string in Unicode normalization form C, for the purposes of re-creating the byte stream accurately from the unicode text. I personally don't think such a requirement is worth saving a few bytes on the wire. |
Hmmm... I did not expect unicode normalization to be a potential issue. I expected that what you send from the browser and what you obtain server side to always be identical. But you are right, in case of doubts and to avoid middleware issues, it might be better to send base64. That seems more bullet proof. ... So everything base64 it shall be😉 ... The single leftover exception is not worth it either. |
But it's sent / received into a Uint8Array which is the problem, so when you change it between bytes to base64 you aren't actually affecting or changing any of these things. |
The spec states that "The user handle MUST NOT contain personally identifying information about the user, such as a username or e-mail address" and "It is RECOMMENDED to let the user handle be 64 random bytes". We should not add features to support a use case we actively recommend against. I think I guess that could be an argument against splitting the root object into two separate types for registration and authentication, but I think that one is fair enough since that is likely how most developers already think of it anyway. |
Agreed |
I haven't chimed in because @dwaite and @emlun beat me to my responses. I'm glad to see my intuition was right about how best to handle those values 🙂 Most of the feedback has been handled on my end. The one outstanding change suggestion that I know about right now is the suggestion to include directions for what to do if bad data is passed into these objects, namely throwing an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from a couple more nits I think this seems good to go for now. I would like to be a bit more rigorous, but I can't see how to do it without essentially spelling out the entire conversions, which seems too obtuse and fragile. This is probably unambiguous enough, we can revise later if we think of a better way to express it. 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot @MasterKale for taking this on!
I like to resolve all comments in my PR's before the changes land, so I'm highlighting the last unresolved comment on this PR. It's a conversation @kreichgauer and I are having on a comment made back in April (we're nearly 100 comments on this 😱): #1703 (comment) Martin mentioned this:
And I responded:
I'm interested in seeing what others might think about what we're discussing. It might be more useful to continue hashing this out down here, though, since it's easier to find. When some kind of decision is reached I can address whatever might need to change, then go back up into the comment and resolve it. |
SHA: 3cdea2b Reason: push, by @MasterKale Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This adds the necessary IDL changes for implementing PublicKeyCredential.toJSON(), and a Blink runtime feature to guard this method. The actual implementation of the method and tests are in a follow-up change. Instances of PublicKeyCredential represent responses to WebAuthn API requests, and toJSON() lets the caller convert a response into a JSON object so it can be serialized and sent to a server. WebAuthn responses inherently need to be verified server-side. However, because they contain values that cannot be serialized by JSON.stringify() (e.g. ArrayBuffers), users of the API previously had to implement serialization themselves. Spec: https://w3c.github.io/webauthn/#dom-publickeycredential-tojson Spec change: w3c/webauthn#1703 Intent to prototype: https://groups.google.com/a/chromium.org/g/blink-dev/c/ePTIazJJ2TA Bug: 1401128 Change-Id: Id87329343269dc54b2e4dbee3fd75d8d83d9945f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4372350 Commit-Queue: Martin Kreichgauer <martinkr@google.com> Auto-Submit: Martin Kreichgauer <martinkr@google.com> Reviewed-by: Rick Byers <rbyers@chromium.org> Reviewed-by: Adam Langley <agl@chromium.org> Cr-Commit-Position: refs/heads/main@{#1128207}
This PR introduces new methods to
PublicKeyCredential
that lean on the client to assist with JSON deserialization ofPublicKeyCredentialCreationOptions
andPublicKeyCredentialRequestOptions
, and JSON serialization ofPublicKeyCredential
output fromnavigator.credentials.create()
andnavigator.credentials.get()
.See Issue #1683 for more context.
Preview | Diff