-
Meet passkeys
It's time for a security upgrade: Learn how to add support for passkeys to create a quick and easy sign in experience for people, all while offering a radical increase to account security. Passkeys are simple and strong credentials built to eliminate phishing attacks. We'll share how passkeys are designed with security in mind, show you how people will use them, go over how to integrate passkeys in your log in flow, and explore the platform and web APIs you need to adopt this feature.
Ressources
Vidéos connexes
WWDC23
WWDC22
- Enhance your Sign in with Apple experience
- Support multiple users in tvOS apps
- What’s new in privacy
WWDC20
-
Rechercher dans cette vidéo…
-
-
11:30 - Associated Domains setup
{ "webcredentials": { "apps": [ "A1B2C3D4E5.com.example.Shiny" ] } } -
11:47 - Annotating user name text field
override func viewDidLoad() { super.viewDidLoad() //Additional setup… userNameField.textContentType = .username } -
11:59 - AutoFill-assisted passkey sign in
// AutoFill-assisted passkey request func signIn() { let challenge: Data = … // Fetched from server let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier: "example.com") let request = provider.createCredentialAssertionRequest( challenge: challenge) let controller = ASAuthorizationController( authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performAutoFillAssistedRequests() } -
13:29 - ASAuthorizationControllerDelegate callback
// Completing a passkey sign in func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { guard let passkeyAssertion = authorization.credential as? ASAuthorizationPlatformPublicKeyCredentialAssertion else { … } let signature = passkeyAssertion.signature let clientDataJSON = passkeyAssertion.rawClientDataJSON // Pass these values to your server, and complete the sign in … } -
16:05 - Modal passkey sign in
// Modal passkey request func signIn() { let challenge: Data = … // Fetched from server let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier: "example.com") let request = provider.createCredentialAssertionRequest( challenge: challenge) let controller = ASAuthorizationController( authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performRequests() } -
16:53 - HTML user name field annotation
<input type="text" id="username-field" autocomplete="username webauthn" > -
17:09 - AutoFill-assisted passkey sign in on the web
// AutoFill-assisted WebAuthn request (JavaScript) function signIn() { if (!PublicKeyCredential.isConditionalMediationAvailable || !PublicKeyCredential.isConditionalMediationAvailable()) { // Browser doesn't support AutoFill-assisted requests. return; } const options = { "publicKey": { challenge: … // Fetched from server }, mediation: "conditional" }; navigator.credentials.get(options) .then(assertion => { // Pass the assertion to your server. }); } -
18:14 - Modal passkey sign in on the web
// Modal WebAuthn request (JavaScript) function signIn() { var options = { "publicKey": { challenge: … // Fetched from server } }; navigator.credentials.get(options) .then(function (assertion) { // Pass the assertion to your server. }); } -
20:55 - Modal passkey request with allow list
// Modal request with allow list func signIn(userName: String) { let challenge: Data = … // Fetched from server let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier:"example.com") let request = provider.createCredentialAssertionRequest( challenge: challenge) let credentialIDs: [Data] = … // Fetched from server for provided userName request.allowedCredentials = credentialIDs.map( ASAuthorizationPlatformPublicKeyCredentialDescriptor.init(credentialID:)) let controller = ASAuthorizationController(authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performRequests() } -
22:56 - Modal passkey request with silent fallback
// Modal passkey request, silent fallback func signIn() { let challenge: Data = … // Fetched from server let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier:"example.com") let request = provider.createCredentialAssertionRequest( challenge: challenge) let controller = ASAuthorizationController(authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performRequests(options: .preferImmediatelyAvailableCredentials) } -
23:06 - Silent fallback delegate callback
// Handling a silent fallback func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { guard let error = error as? ASAuthorizationError else { … } if error.code == .canceled { // Either the user canceled the sheet, or there were no credentials available. showSignInForm() } } -
24:40 - Combined credential request
// Combined credential modal request func signIn() { let challenge: Data = … // Fetched from server let passkeyProvider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier:"example.com") let passkeyRequest = passkeyProvider.createCredentialAssertionRequest( challenge: challenge) let passwordRequest = ASAuthorizationPasswordProvider().createRequest() let signInWithAppleRequest = ASAuthorizationAppleIDProvider().createRequest() let controller = ASAuthorizationController( authorizationRequests: [passkeyRequest, passwordRequest, signInWithAppleRequest]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performRequests() } -
25:02 - Combined credential callback
// Completing a combined credential request func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { switch authorization.credential { case let passkeyAssertion as ASAuthorizationPlatformPublicKeyCredentialAssertion: finishSignIn(with: passkeyAssertion) case let signInWithAppleCredential as ASAuthorizationAppleIDCredential: finishSignIn(with: signInWithAppleCredential) case let passwordCredential as ASPasswordCredential: finishSignIn(with: passwordCredential) default: // Handle other credential types break } }
-