Zum Hauptinhalt springen

Create a challenge to register a new passkey

POST/v2/users/self/passkey-registration-challenges
API-Version
v2
Request-Methode
POST
Operation-ID
user-create-passkey-registration-challenge

Confirm your identity with the password and, if a second factor is set up, with multiFactorCode or passkeyCredential.

Request​

Responses​

Format
application/json
Beschreibung

The challenge has been created.

  • challengeIdstring (uuid)required
  • optionsobjectrequired

    Options for registering a passkey, as WebAuthn Level 3 PublicKeyCredentialCreationOptionsJSON‍. Pass the object unchanged to PublicKeyCredential.parseCreationOptionsFromJSON()‍ and the result as publicKey to navigator.credentials.create(). Send the resulting credential back as credential.toJSON()‍ together with the challengeId the options came with. Binary values are base64url-encoded without padding.

    • attestationstringrequired

      Always none; the API does not check which authenticator model created the passkey.

    • attestationFormatsArray von string

      Not set by this API.

      • Array[
        • *string
        ]
    • authenticatorSelectionobjectrequired

      Always a discoverable credential (residentKey: required) with user verification (userVerification: required); no authenticatorAttachment, so the browser also offers other devices (QR code).

      • authenticatorAttachmentstring
      • requireResidentKeyboolean
      • residentKeystring
      • userVerificationstring
    • challengestringrequired

      32 random bytes, base64url-encoded without padding. Can be used once.

    • excludeCredentialsArray von objectrequired

      The passkeys the user already has for this relying party; the authenticator does not register them again.

      • Array[

        A passkey of the user, as WebAuthn Level 3 PublicKeyCredentialDescriptorJSON‍.

        • *object

          A passkey of the user, as WebAuthn Level 3 PublicKeyCredentialDescriptorJSON‍.

          • idstringrequired

            The credential id, base64url-encoded without padding.

          • transportsArray von string

            How the browser can reach the authenticator, as reported at registration (internal, hybrid, usb, nfc, ble, smart-card).

            • Array[
              • *string
              ]
          • typestringrequired

            The credential type, always public-key.

        ]
    • extensionsobject
    • hintsArray von string

      Hints for the browser which authenticator to offer. Not set by this API.

      • Array[
        • *string
        ]
    • pubKeyCredParamsArray von objectrequired

      The accepted key types, ES256 (-7) and RS256 (-257).

      • Array[
        • *object
          • algintegerrequired

            A COSE algorithm identifier.

          • typestringrequired

            Always public-key.

        ]
    • rpobjectrequired

      The relying party, selected from the Origin header of the request that created the challenge.

      • idstringrequired
      • namestringrequired
    • timeoutintegerrequired

      Milliseconds until the challenge expires.

    • userobjectrequired

      The user the passkey is created for, as WebAuthn Level 3 PublicKeyCredentialUserEntityJSON‍.

      • displayNamestringrequired

        First and last name of the user, or the email address if both are empty.

      • idstringrequired

        The UTF-8 bytes of the user id, base64url-encoded without padding. A passkey login returns it as response.userHandle.

      • namestringrequired

        The verified email address of the user.

Content-Type: application/json

{
"challengeId": "6a1f0b1e-7d0c-4a43-9c1f-4f6c9b0f7a11",
"options": {
"attestation": "none",
"authenticatorSelection": {
"requireResidentKey": true,
"residentKey": "required",
"userVerification": "required"
},
"challenge": "rcUa1634YUaCsBeasroTVudBb4jNSnKzTGzJ9EdLlrA",
"excludeCredentials": [
{
"id": "Y3JlZGVudGlhbC1pZA",
"transports": [
"internal"
],
"type": "public-key"
}
],
"extensions": {
"credProps": true
},
"hints": [],
"pubKeyCredParams": [
{
"alg": -7,
"type": "public-key"
},
{
"alg": -257,
"type": "public-key"
}
],
"rp": {
"id": "mittwald.de",
"name": "mittwald"
},
"timeout": 300000,
"user": {
"displayName": "Ada Lovelace",
"id": "NmMxYzFkMGUtNmYwZS00YTNjLTlkM2YtNWYyZDFkMGI5YTEx",
"name": "a.lovelace@example.com"
}
}
}
{
"description": "A challenge for registering a passkey. Run `navigator.credentials.create()` with `options` and send\n`challengeId` together with the resulting `credential.toJSON()` to `POST /users/self/passkeys`. The challenge\ncan be used once.\n",
"properties": {
"challengeId": {
"example": "6a1f0b1e-7d0c-4a43-9c1f-4f6c9b0f7a11",
"format": "uuid",
"type": "string"
},
"options": {
"description": "Options for registering a passkey, as WebAuthn Level 3\n[`PublicKeyCredentialCreationOptionsJSON`](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialcreationoptionsjson).\nPass the object unchanged to\n[`PublicKeyCredential.parseCreationOptionsFromJSON()`](https://www.w3.org/TR/webauthn-3/#sctn-parseCreationOptionsFromJSON)\nand the result as `publicKey` to `navigator.credentials.create()`. Send the resulting credential back as\n[`credential.toJSON()`](https://www.w3.org/TR/webauthn-3/#dom-publickeycredential-tojson) together with the\n`challengeId` the options came with. Binary values are base64url-encoded without padding.\n",
"example": {
"attestation": "none",
"authenticatorSelection": {
"requireResidentKey": true,
"residentKey": "required",
"userVerification": "required"
},
"challenge": "rcUa1634YUaCsBeasroTVudBb4jNSnKzTGzJ9EdLlrA",
"excludeCredentials": [
{
"id": "Y3JlZGVudGlhbC1pZA",
"transports": [
"internal"
],
"type": "public-key"
}
],
"extensions": {
"credProps": true
},
"hints": [],
"pubKeyCredParams": [
{
"alg": -7,
"type": "public-key"
},
{
"alg": -257,
"type": "public-key"
}
],
"rp": {
"id": "mittwald.de",
"name": "mittwald"
},
"timeout": 300000,
"user": {
"displayName": "Ada Lovelace",
"id": "NmMxYzFkMGUtNmYwZS00YTNjLTlkM2YtNWYyZDFkMGI5YTEx",
"name": "a.lovelace@example.com"
}
},
"properties": {
"attestation": {
"description": "Always `none`; the API does not check which authenticator model created the passkey.",
"example": "none",
"type": "string"
},
"attestationFormats": {
"description": "Not set by this API.",
"items": {
"type": "string"
},
"type": "array"
},
"authenticatorSelection": {
"description": "Always a discoverable credential (`residentKey: required`) with user verification\n(`userVerification: required`); no `authenticatorAttachment`, so the browser also offers other devices\n(QR code).\n",
"properties": {
"authenticatorAttachment": {
"type": "string"
},
"requireResidentKey": {
"example": true,
"type": "boolean"
},
"residentKey": {
"example": "required",
"type": "string"
},
"userVerification": {
"example": "required",
"type": "string"
}
},
"type": "object"
},
"challenge": {
"description": "32 random bytes, base64url-encoded without padding. Can be used once.",
"example": "rcUa1634YUaCsBeasroTVudBb4jNSnKzTGzJ9EdLlrA",
"type": "string"
},
"excludeCredentials": {
"description": "The passkeys the user already has for this relying party; the authenticator does not register them again.",
"items": {
"description": "A passkey of the user, as WebAuthn Level 3\n[`PublicKeyCredentialDescriptorJSON`](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialdescriptorjson).\n",
"example": {
"id": "AN29uP9UVfVZ1X0WLKg3zA",
"transports": [
"hybrid",
"internal"
],
"type": "public-key"
},
"properties": {
"id": {
"description": "The credential id, base64url-encoded without padding.",
"example": "AN29uP9UVfVZ1X0WLKg3zA",
"type": "string"
},
"transports": {
"description": "How the browser can reach the authenticator, as reported at registration (`internal`, `hybrid`, `usb`,\n`nfc`, `ble`, `smart-card`).\n",
"example": [
"hybrid",
"internal"
],
"items": {
"type": "string"
},
"type": "array"
},
"type": {
"description": "The credential type, always `public-key`.",
"example": "public-key",
"type": "string"
}
},
"required": [
"type",
"id"
],
"type": "object"
},
"type": "array"
},
"extensions": {
"description": "WebAuthn Level 3\n[`AuthenticationExtensionsClientInputsJSON`](https://www.w3.org/TR/webauthn-3/#dictdef-authenticationextensionsclientinputsjson).\n",
"type": "object"
},
"hints": {
"description": "Hints for the browser which authenticator to offer. Not set by this API.",
"items": {
"type": "string"
},
"type": "array"
},
"pubKeyCredParams": {
"description": "The accepted key types, ES256 (`-7`) and RS256 (`-257`).",
"items": {
"properties": {
"alg": {
"description": "A COSE algorithm identifier.",
"example": -7,
"type": "integer"
},
"type": {
"description": "Always `public-key`.",
"example": "public-key",
"type": "string"
}
},
"required": [
"type",
"alg"
],
"type": "object"
},
"type": "array"
},
"rp": {
"description": "The relying party, selected from the `Origin` header of the request that created the challenge.",
"properties": {
"id": {
"example": "mittwald.de",
"type": "string"
},
"name": {
"example": "mittwald",
"type": "string"
}
},
"required": [
"name",
"id"
],
"type": "object"
},
"timeout": {
"description": "Milliseconds until the challenge expires.",
"example": 300000,
"type": "integer"
},
"user": {
"description": "The user the passkey is created for, as WebAuthn Level 3\n[`PublicKeyCredentialUserEntityJSON`](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialuserentityjson).\n",
"properties": {
"displayName": {
"description": "First and last name of the user, or the email address if both are empty.",
"example": "Ada Lovelace",
"type": "string"
},
"id": {
"description": "The UTF-8 bytes of the user id, base64url-encoded without padding. A passkey login returns it as\n`response.userHandle`.\n",
"example": "NmMxYzFkMGUtNmYwZS00YTNjLTlkM2YtNWYyZDFkMGI5YTEx",
"type": "string"
},
"name": {
"description": "The verified email address of the user.",
"example": "a.lovelace@example.com",
"type": "string"
}
},
"required": [
"id",
"name",
"displayName"
],
"type": "object"
}
},
"required": [
"rp",
"user",
"challenge",
"pubKeyCredParams",
"timeout",
"excludeCredentials",
"authenticatorSelection",
"attestation"
],
"type": "object"
}
},
"required": [
"challengeId",
"options"
],
"type": "object"
}

Format
application/json
Beschreibung

An additional second factor code is necessary to process the request.

  • *
Content-Type: application/json

null
{
"allOf": [
{
"properties": {
"info": {
"description": "A json object, given further information about the error",
"type": "object"
},
"message": {
"description": "Some more detailed information about the error",
"type": "string"
},
"name": {
"description": "Unique key for the error type",
"type": "string"
}
},
"required": [
"name",
"message"
],
"type": "object"
},
{
"properties": {
"name": {
"enum": [
"SecondFactorRequired"
],
"type": "string"
}
},
"required": [
"name"
],
"type": "object"
}
]
}

Nutzungsbeispiele​

$ curl \
--fail \
--location \
-X POST \
-d '{"multiFactorCode":"123456","passkeyCredential":{"challengeId":"6a1f0b1e-7d0c-4a43-9c1f-4f6c9b0f7a11","credential":{"authenticatorAttachment":"platform","clientExtensionResults":{},"id":"AN29uP9UVfVZ1X0WLKg3zA","rawId":"AN29uP9UVfVZ1X0WLKg3zA","response":{"authenticatorData":"8q2Xwa9qKcqUca3Qox8O-H9rqwjlNp1O5WHPOETZnigdAAAAAA","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoicmNVYTE2MzRZVWFDc0JlYXNyb1RWdWRCYjRqTlNuS3pUR3pKOUVkTGxyQSIsIm9yaWdpbiI6Imh0dHBzOi8vc3R1ZGlvLm1pdHR3YWxkLmRlIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ","signature":"MEUCIQD7nQ352E7fNAwHcgq5mMDsoeHQ0odAgekdw9tbs-Lc1gIgSBt2yLdJV_AcNx76CMsEP-S7LoJ_E0q-y19EAEWtwLI","userHandle":"NmMxYzFkMGUtNmYwZS00YTNjLTlkM2YtNWYyZDFkMGI5YTEx"},"type":"public-key"}},"password":"string"}' \
-H "Authorization: Bearer $MITTWALD_API_TOKEN" \
-H 'Content-Type: application/json' \
https://api.mittwald.de/v2/users/self/passkey-registration-challenges
import { MittwaldAPIV2Client } from "@mittwald/api-client";
import { assertStatus } from "@mittwald/api-client-commons";

const client = MittwaldAPIClient.newWithToken(process.env.MITTWALD_API_TOKEN);
const response = await client.user.createPasskeyRegistrationChallenge({
"data": {
"multiFactorCode": "123456",
"passkeyCredential": {
"challengeId": "6a1f0b1e-7d0c-4a43-9c1f-4f6c9b0f7a11",
"credential": {
"authenticatorAttachment": "platform",
"clientExtensionResults": {},
"id": "AN29uP9UVfVZ1X0WLKg3zA",
"rawId": "AN29uP9UVfVZ1X0WLKg3zA",
"response": {
"authenticatorData": "8q2Xwa9qKcqUca3Qox8O-H9rqwjlNp1O5WHPOETZnigdAAAAAA",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoicmNVYTE2MzRZVWFDc0JlYXNyb1RWdWRCYjRqTlNuS3pUR3pKOUVkTGxyQSIsIm9yaWdpbiI6Imh0dHBzOi8vc3R1ZGlvLm1pdHR3YWxkLmRlIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ",
"signature": "MEUCIQD7nQ352E7fNAwHcgq5mMDsoeHQ0odAgekdw9tbs-Lc1gIgSBt2yLdJV_AcNx76CMsEP-S7LoJ_E0q-y19EAEWtwLI",
"userHandle": "NmMxYzFkMGUtNmYwZS00YTNjLTlkM2YtNWYyZDFkMGI5YTEx"
},
"type": "public-key"
}
},
"password": "string"
}
});

assertStatus(response, 201);

use \Mittwald\ApiClient\Generated\V2\Clients\User\CreatePasskeyRegistrationChallenge\CreatePasskeyRegistrationChallengeRequest;
use \Mittwald\ApiClient\Generated\V2\Clients\User\CreatePasskeyRegistrationChallenge\CreatePasskeyRegistrationChallengeRequestBody;

$client = MittwaldAPIClient::newWithToken(getenv('MITTWALD_API_TOKEN'));

// TODO: Please consult the properties and constructor signature of
// CreatePasskeyRegistrationChallengeRequestBody to learn how to construct a valid instance
$body = new CreatePasskeyRegistrationChallengeRequestBody(/* TODO: ... */);

$request = (new CreatePasskeyRegistrationChallengeRequest(
body: $body
));
$response = $client->user()->createPasskeyRegistrationChallenge($request);

var_dump($response->getBody();

Auf dieser Seite