Skip to content

Commit 6d14424

Browse files
committed
Add missing base64url decoding step to getting started instructions
1 parent 05e155b commit 6d14424

File tree

1 file changed

+45
-4
lines changed

1 file changed

+45
-4
lines changed

README

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,35 @@ Now call the WebAuthn API on the client side:
197197

198198
[source,javascript]
199199
----------
200+
function base64urlToUint8array(base64Bytes) {
201+
const padding = '===='.substring(0, (4 - (base64Bytes.length % 4)) % 4);
202+
return base64js.toByteArray((base64Bytes + padding).replace(/\//g, "_").replace(/\+/g, "-"));
203+
}
200204
function uint8arrayToBase64url(bytes) {
201205
return base64js.fromByteArray(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
202206
}
203207

204208
fetch(/* ... */) // Make the call that returns the credentialCreateJson above
205-
.then(credentialCreateJson => // Call WebAuthn ceremony
206-
navigator.credentials.create(credentialCreateJson))
209+
.then(credentialCreateJson => ({ // Decode byte arrays from base64url
210+
publicKey: {
211+
...credentialCreateJson.publicKey,
212+
213+
challenge: base64urlToUint8Array(credentialCreateJson.publicKey.challenge),
214+
user: {
215+
...credentialCreateJson.publicKey.user,
216+
id: base64urlToUint8Array(credentialCreateJson.publicKey.user.id),
217+
},
218+
excludeCredentials: credentialCreateJson.publicKey.excludeCredentials.map(credential => ({
219+
...credential,
220+
id: base64urlToUint8Array(credential.id),
221+
})),
222+
223+
// Warning: Extension inputs could also contain binary data that needs encoding
224+
extensions: credentialCreateJson.publicKey.extensions,
225+
},
226+
}))
227+
.then(credentialCreateOptions => // Call WebAuthn ceremony
228+
navigator.credentials.create(credentialCreateOptions))
207229
.then(publicKeyCredential => ({ // Encode PublicKeyCredential for transport to server (example)
208230
type: publicKeyCredential.type,
209231
id: publicKeyCredential.id,
@@ -287,13 +309,32 @@ Now call the WebAuthn API on the client side:
287309

288310
[source,javascript]
289311
----------
312+
function base64urlToUint8array(base64Bytes) {
313+
const padding = '===='.substring(0, (4 - (base64Bytes.length % 4)) % 4);
314+
return base64js.toByteArray((base64Bytes + padding).replace(/\//g, "_").replace(/\+/g, "-"));
315+
}
290316
function uint8arrayToBase64url(bytes) {
291317
return base64js.fromByteArray(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
292318
}
293319

294320
fetch(/* ... */) // Make the call that returns the credentialGetJson above
295-
.then(credentialGetJson => // Call WebAuthn ceremony
296-
navigator.credentials.get(credentialGetJson))
321+
.then(credentialGetJson => ({ // Decode byte arrays from base64url
322+
publicKey: {
323+
...credentialGetJson.publicKey,
324+
allowCredentials: credentialGetJson.publicKey.allowCredentials
325+
&& credentialGetJson.publicKey.allowCredentials.map(credential => ({
326+
...credential,
327+
id: base64urlToUint8Array(credential.id),
328+
})),
329+
330+
challenge: base64urlToUint8Array(credentialGetJson.publicKey.challenge),
331+
332+
// Warning: Extension inputs could also contain binary data that needs encoding
333+
extensions: credentialGetJson.publicKey.extensions,
334+
},
335+
}))
336+
.then(credentialGetOptions => // Call WebAuthn ceremony
337+
navigator.credentials.get(credentialGetOptions))
297338
.then(publicKeyCredential => ({ // Encode PublicKeyCredential for transport to server (example)
298339
type: publicKeyCredential.type,
299340
id: publicKeyCredential.id,

0 commit comments

Comments
 (0)