Giter Club home page Giter Club logo

corbado / flutter-passkeys Goto Github PK

View Code? Open in Web Editor NEW
44.0 4.0 13.0 15.38 MB

Easily provide passkey authentication based on FIDO2 / WebAuthn for Flutter apps (iOS & Android) via a dedicated Flutter package

Home Page: https://www.corbado.com/passkeys/flutter

License: BSD 3-Clause "New" or "Revised" License

Java 3.55% Objective-C 0.01% Dart 38.95% C++ 1.53% C 0.07% CMake 1.63% Swift 1.50% Kotlin 0.02% Ruby 0.46% HTML 0.26% Shell 0.32% JavaScript 3.03% TypeScript 48.67%
android dart faceid fido2 flutter ios kotlin package passkey passkeys swift touchid webauthn

flutter-passkeys's Introduction

GitHub Repo Cover

Flutter passkeys

Flutter packages to enable passkey authentication (based on WebAuthn / FIDO2).

Android iOS Linux macOS Web Windows
Support

passkey-signup

Current list of packages

1. Passkeys

Description

A Flutter package that enables simple passkey authentication. Currently Android and iOS are supported.

Features

  • sign up and login users with passkeys
  • connect your own relying party server or use pre-implemented ones

Read more

2. Corbado Auth

Description

A Flutter package that builds on the passkeys package. It adds additional functionalities to make it simpler to use passkey authentication in your own Flutter app.

Features

  • sign up and login users with passkeys
  • connect Corbado as pre-implemented relying party server
  • keep users logged in even if they close the app (automatic session refresh)

Read more

3. Corbado Auth Firebase

A Flutter package that builds on the corbado_auth and the passkeys package. It helps you to integrate passkey authentication into your Flutter app that uses Firebase as a backend.

Features

  • allow new users to sign up and log in using passkeys
  • allow existing users (that you created with Firebase authentication) to setup a passkey and then log in with it
  • email OTP codes as fallback mechanism for situations when passkeys can not be used (e.g. when a user logs in to a device where none of his passkeys is available)

Read more

Contributing

We're happy to receive your pull requests. For major changes, please open an issue first to discuss what you would like to change.

Support

If you have questions, feedback or wishes regarding features, please reach out to us via email or join our passkeys community on Slack.

License

BSD-3-clause

flutter-passkeys's People

Contributors

briancorbin avatar incorbador avatar lukaskratzel avatar nicolaistein avatar nielsenko avatar varunlohade avatar vincentdelitz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

flutter-passkeys's Issues

Support for roaming authenticator/hardware security key

Have you considered to add support for roaming authenticators to ios/android?

When using the javascript webauthn APIs (through iOS webview), a following dialog is shown:
Screenshot 2024-02-02 at 13 11 12
This provides an easy way to use same client code for both passkeys and security keys. However, when using the flutter library, as shown in your example app, there is only the passkeys option.

Thanks anyway for publishing the library, it has helped me greatly with my experiments on flutter and passkeys 👍

How to retrieve the public key?

I'm following the example code on the documention, and throughout the whole process of sign up / sign in, it is not clear to me, where or what is the public key that I should use to verify user sign in requests.

When calling PasskeyAuthenticator().register(...) I get back in the response a RegisterResponseType object, that only contains the following information:

final String id;
final String rawId;
final String clientDataJSON;
final String attestationObject;

By decoding clientDatajSON I was able to recover more information about the passkey, such as id, challenge... But nothing related to the public key. What value should I use on my RelayingParty server as the public key for the created user?

Update loginWithPasskey to support automatic conditionalUI for iOS

Currently we only support performAutoFillAssistedRequests on iOS. Therefore it is not possible to automatically trigger a conditionalUI popup. Users can therefore complete conditional UI only through their keyboard.

Proposal:
Add another parameter to the loginWithPasskey method called "keyboardIntegrated: boolean". This allows for the following combinations:

  • conditional: false, keyboardIntegrated: false (Android, iOS, Web)
  • conditional: true, keyboardIntegrated: false (Android, iOS, Web)
  • conditional: true, keyboardIntegrated: true (iOS)

missing `icon` in extension.yaml

Hey, through the review process for your extension, I noticed you're missing an icon, that is important for showing it in the marketplace. You can add one and send it for review again.

Find the docs on how to add it here.

Conceptialize example 1 (app + custom backend)

Intro

To publish our plugin we must present its usage by including examples to it. Currently two main scenarios come to my mind that can be represented in an example each. The first one combines the app where the user signs in using passkeys with a custom backend (this serves data to the app).

Description

Before we write the example we must think of how the app will communicate:

  • with the Corbado API: initially there will be interaction for the register and the login, but must there be refreshes?
  • with the custom backend: the app must authenticate itself by including a token and thus proving that a user is signed in

Implementation idea

Unable to build iOS after plugin update from 1.1.0 to 2.0.7

I've updated passkeys plugin from 1.1.0 to 2.0.7 I'm getting error while building for iOS
Swift Compiler Error (Xcode): Value of type 'ASAuthorizationPlatformPublicKeyCredentialRegistrationRequest' has no member 'excludedCredentials'
.pub-cache/hosted/pub.dev/passkeys_ios-2.0.3/ios/Classes/PasskeysPlugin.swift:56:20

Add android platform package

Intro

A new structure has been introduced for our flutter plugin on branch feature/prepare-opensource. This will become our temporary main branch where we develop a version 1 for our open source flutter plugin. See the README.md on that branch for more details on the basic ideas of that new structure (federated plugins, pigeons, openapi-generator).

Description

Currently, only the iOS platform package has been implemented.
Add the android one in this task.
Please stick with the iOS approach, i.e.:

  • add the android implementation as one more federated plugin
  • use pigeons to generate the channel code that glues flutter with android

Testing

Currently, we still do manual testing.
So for e2e manual testing start the example add in passkeys/example/lib/main.dart on an Android emulator and make sure that all three buttons work:

  • "canAuthenticate" should return true
  • "register" should guide the user through the registration flow => this is completed as soon as the user receives a confirmation email ("Confirm your sign up request to..." => confirm that email otherwise authentication seems not to work)
  • "authenticate" should guide the user through the authentication flow

Implementation idea

  • Take a look at some of the plugins in https://github.com/flutter/packages/tree/main/packages for inspiration (the plugins with real platform dependencies are the most interesting ones, e.g. image_picker, local_auth)
  • Branch from feature/prepare-opensource and add the android package
  • Then create a PR back to feature/prepare-opensource

sign up and get "Socket operation failed"

I clone the project and run on a physical and virtual pixal 6a
but when I signing up, I alway got "Socket operation failed"
after I change api on api_client.dart from "https://.frontendapi.corbado.io" to "https://api.eu-1.corbado.io" which works on live demo but still got the same errror
please tell me how to do with that, thanks

Error in web application when running build_runner with corbado_auth package

To generate code for other packages I do a build_runner build before starting the app, but when I do this I get a white page and following error message
Rejecting promise with error: TypeError: Cannot read properties of undefined (reading 'init')

To replicate this problem, have the following setup:
New blank Flutter (v3.19.6) project
add corbado_auth: ^2.0.7 dependency
add build_runner: ^2.4.9 dev-dependency
run dart run build_runner build
try to start the app in a web application

Can not register passkey on iOS Simulator with local RelyingPartyServer

Code:

final passkeyAuthenticator = PasskeyAuthenticator();

    // initiate sign up by calling the relying party server
    final webAuthnChallenge = await _dio.post(
        'http://localhost:19200/v1/auth/register/passkey/initiate',
        data: {'email': '[email protected]'});

    // call the platform authenticator to register a new passkey on the device
    final platformRes = await passkeyAuthenticator.register(webAuthnChallenge); // <--- Exception is thrown here

Error:

PlatformException (PlatformException(decodingChallenge, CustomErrors, Stacktrace: ["0   passkeys_ios                        0x000000010d21d654 $s12passkeys_ios9wrapError33_F74ED722C198BB4137EE305712CCDE86LLySayypSgGypF + 1588", "1   passkeys_ios                        0x000000010d22357f $s12passkeys_ios16PasskeysApiSetupC5setUp15binaryMessenger3apiySo013FlutterBinaryI0_p_AA0cD0_pSgtFZyypSg_yAJctcfU0_ys6ResultOyAA16RegisterResponseVs5Error_pGcfU_ + 559", "2   passkeys_ios                        0x000000010d226f67 $s12passkeys_ios14PasskeysPluginC8register9challenge12relyingParty4user10completionySS_AA07RelyingH0VAA4UserVys6ResultOyAA16RegisterResponseVs5Error_pGctF + 1591", "3   passkeys_ios                        0x000000010d227ed1 $s12passkeys_ios14PasskeysPluginCAA0C3ApiA2aDP8register9challenge12relyingParty4user10completionySS_AA07RelyingI0VAA4UserVys6ResultOyAA16RegisterResponseVs5Error_pGctFTW + 113", "4   passkeys_ios                        0x000000010d2232e3 $s12passkeys_ios16PasskeysApiSetupC5setUp15binaryMessenger3apiySo013FlutterBinaryI0_p_AA0cD0_pSgtFZyypSg_yAJctcfU0_ + 1459", "5   passkeys_ios                        0x000000010d222c31 $sypSgAAIegn_Iegng_yXlSgABIeyBy_IeyByy_TR + 225", "6   Flutter                             0x00000001187f863d __48-[FlutterBasicMessageChannel setMessageHandler:]_block_invoke + 171", "7   Flutter                             0x00000001181b0222 ___ZN7flutter25PlatformMessageHandlerIos21HandlePlatformMessageENSt21_LIBCPP_ABI_NAMESPACE10unique_ptrINS_15PlatformMessageENS1_14default_deleteIS3_EEEE_block_invoke + 94", "8   libdispatch.dylib                   0x00007ff800156a90 _dispatch_call_block_and_release + 12", "9   libdispatch.dylib                   0x00007ff800157d3a _dispatch_client_callout + 8", "10  libdispatch.dylib                   0x00007ff800166ac0 _dispatch_main_queue_drain + 1420", "11  libdispatch.dylib                   0x00007ff800166526 _dispatch_main_queue_callback_4CF + 31", "12  CoreFoundation                      0x00007ff8003f5850 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9", "13  CoreFoundation                      0x00007ff8003f018b __CFRunLoopRun + 2463", "14  CoreFoundation                      0x00007ff8003ef409 CFRunLoopRunSpecific + 557", "15  GraphicsServices                    0x00007ff80fcdd187 GSEventRunModal + 137", "16  UIKitCore                           0x00007ff805b703a2 -[UIApplication _run] + 972", "17  UIKitCore                           0x00007ff805b74e10 UIApplicationMain + 123", "18  Runner                              0x000000010be632bf main + 63", "19  dyld                                0x000000010bf3c3ee start_sim + 10", "20  ???                                 0x00000001180763a6 0x0 + 4698104742"], null))

Some of the RP server data for registration options:

const options = await generateRegistrationOptions({
      "Vlatko",
      "localhost",
      userID: user.id,
      userName: user.email,
      // Don't prompt users for additional information about the authenticator
      // (Recommended for smoother UX)
      attestationType: "none",
      // See "Guiding use of authenticators via authenticatorSelection" below
      authenticatorSelection: {
        // Defaults
        residentKey: "preferred",
        userVerification: "preferred",
        // Optional
        authenticatorAttachment: "platform"
      },
    });

Error when registering passkey on Android

I'm running in to an error when registering a passkey only on Android, iOS works just fine. Any idea what is causing this?

PlatformException(android-unhandledGoogle Password Manager, UNKNOWN EXCEPTION - java.lang.IllegalArgumentException: bad base-64, UNKNOWN EXCEPTION - java.lang.IllegalArgumentException: bad base-64, null)

For reference, here is the code I am running, and it is failing at the final registerRequestResponse = await passkeyAuthenticator.register(registerRequest); line during registration.

I have confirmed my google account and google play are set up correctly, as I am able to get the initial prompt to register the passkey, but upon clicking "Continue" it fails and errors out.
Screenshot 2024-03-25 at 4 58 12 PM

final userHandle = CryptoRNG().generate();
final userHandleEncoded = base64Encode(userHandle);
final passkeyAuthenticator = PasskeyAuthenticator();
final supportsPasskeys = await passkeyAuthenticator.canAuthenticate();
print(supportsPasskeys);
final registerRequest = RegisterRequestType(
  challenge: base64.encode(CryptoRNG().generate()),
  relyingParty: RelyingPartyType(
      name: 'Capsule', id: relyingPartyId ?? environment.relyingPartyId()),
  user: UserType(displayName: email, name: email, id: userHandleEncoded),
  authSelectionType: AuthenticatorSelectionType(
      authenticatorAttachment: 'platform',
      requireResidentKey: true,
      residentKey: 'required',
      userVerification: 'required'),
  pubKeyCredParams: [
    PubKeyCredParamType(
        type: PublicKeyCredentialType.publicKey.value, alg: es256Algorithm),
    PubKeyCredParamType(
        type: PublicKeyCredentialType.publicKey.value, alg: rs256Algorithm),
  ],
  timeout: 60000,
  attestation: 'direct',
  excludeCredentials: [],
);

final registerRequestResponse =
    await passkeyAuthenticator.register(registerRequest);

Unable to login on Passkeys.eu

When I created an account on iOS and tried to log in from Android, it didn't work. But when I created an account on Android and then logged in from iOS, it worked fine using your website passkeys.eu.

Why am I unable to log in from Android after creating an account using an iOS device?

Ability to cancel and retry authorization or registration

Hello,

I've encountered situations with iOS where an error gets thrown when authenticateWithAutoComplete is triggered:
ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "(null)"

And when a subsequent call to authenticateWithEmail is triggered, this error gets thrown:
flutter: PlatformException(failed, The operation couldn’t be completed. Request already in progress for specified application identifier., , null)

It would be extremely helpful if PasskeyAuth can auto-cancel via something like ASAuthorizationController or if a cancel method is provided on the interface that can be programmatically invoked.

Environment Details

Flutter 3.16.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision db7ef5bf9f (2 weeks ago) • 2023-11-15 11:25:44 -0800
Engine • revision 74d16627b9
Tools • Dart 3.2.0 • DevTools 2.28.2

Real iPhone, iOS version 17.1.1

My flutter app is fully configured to support passkeys. Associated domains fully configured. Our domain's apple-app-site-association can be reached by Apple's CDN (https://app-site-association.cdn-apple.com/a/v1/our-domain

And thank you providing this excellent package to the community!

Android 10 Passkey authentication issue help

Have a wonderful day, everyone!
I'm implementing Passkey for my application with your Passkeys package, it's really great. Along with that, I am also implementing a relying party server.

I'm encountering some issues on Android 10. Specifically, the register flow works fine, but when I try to log in, I get the following error: Google Sign-In (beginSignIn) fails with Missing Feature{name=auth_api_credentials_begin_sign_in, version=8}
=> But I've tried it on Android 13 and both register/login work fine)

Attached to the post is CreationOptions when creating Passkey

Screenshot 2024-03-18 at 13 13 38

Please help me. Special thanks.

Fix incomplete registers

Description

Currently, if a user cancels the signup he can not restart the signup because the user itself is already existing in our backend as the first register call has been made.

Testing

After canceling my register attempt I should be able to start a new one with the same email address.

Implementation idea

Not sure yet what the best solution for that problem is:

  • deleting the user from the app is not working (we can probably not allow that to be done over the public API if the user is unauthenticated)
  • we could alter the backend to allow "overwriting" a user if that user is in incomplete state (not trivial though, if implemented in this simple form it could allow stealing between users if the perfectly time this) => for this task we probably have to talk to someone familiar with the backend API and bounce some ideas.

Conceptialize example 2 (app + Firebase)

Intro

To publish our plugin we must present its usage by including examples to it. Currently two main scenarios come to my mind that can be represented in an example each. The second one combines the app where the user signs in using passkeys with firebase (this serves data to the app). As Firebase is probably the default solution for small teams and individual programmers we should also show how to use passkeys with Firebase.

Description

Before we write the example we must think of how the app will communicate.
Then we can put a few ideas together what the example should include.

Implementation idea

  • register and login can be done the normal way (direct communication to Corbado Frontend API)
  • the login call returns a Corbado token
  • this token can be exchanged to a Firebase JWT token by calling a Firebase cloud function => this cloud function must validate the token (either by just looking at it or by calling Corbado's API) and must create the Firebase JWT token
  • the cloud function will be written and provided by us (Firebase has a concept of "extensions" for that and can be installed by users by a click
  • finally the app can call signInWithCustom token (using the Firebase JWT) => now all firebase services can be used just as normal
image

Fill user.email value in example

Background
Currently, in the example, we use the email address as the "name" and leave the email field blank when creating a new user, as there is no username field in the example.

TODO
Can we please add the email also to the corresponding email address field in the backend.

Support of other platforms

I'm just starting a small passkey research and found this flutter plugin. Do you plan to extend the support for the desktop and web platforms?

Android 12 passkey authentication issue help

Hello,

Our flutter android app registration flow with passkeys is working fine but the login/authenticate flow is not working. Not sure how to debug this exception:
PlatformException(android-no-credential, During begin sign in, failure response from one tap: 16: Cannot find a matching credential., , null)

Not sure why android can't find a matching credential when the registration was successful.

All configurations outlined here https://developer.android.com/training/sign-in/passkeys were followed. Not sure, what is missing. If it helps, the registration UI looks like this and the flow works fine.

IMG_9621

When we logout and log back in using the authenticate flow, the error above is thrown.

Environment Details
Flutter 3.16.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision db7ef5bf9f (2 weeks ago) • 2023-11-15 11:25:44 -0800
Engine • revision 74d16627b9
Tools • Dart 3.2.0 • DevTools 2.28.2

Real Pixel 3 XL, Android version 12

Our flutter app is fully configured to support passkeys. Support for digital asset links has been added.

And thank you providing this excellent package to the community!

Signing profile?

I tried to use the passkeys/passkeys/example with an iPhone14 simulator, but you may need to provide an xcode signing profile to allow simulators to use the corbado domains. This is what I get when I try to signup:
A Dart VM Service on iPhone 14 is available at: http://127.0.0.1:58211/8JIzFRpqDNo=/
The Flutter DevTools debugger and profiler on iPhone 14 is available at:
http://127.0.0.1:9101?uri=http://127.0.0.1:58211/8JIzFRpqDNo=/
flutter: PlatformException(domain-not-associated, The operation couldn’t be completed. Application with identifier YEFSQLA92K.com.corbado.passkeys.pub is not associated with domain pro-6244024196016258271.frontendapi.corbado.io, , null)

flutter: CorbadoPasskeyBackend: pro-6244024196016258271

Public Key Issue

I got this error when I use SignUp....

The user is registered OK but it throw me that error, then if I try to signing, it throw me a snackbar "Instance of No PasskeyForDeviceException".
(I have been using fingerfrint passkey with other app the same phone)

Screenshot_2023-10-26-12-48-32-346_com corbado passkeys pub

Update from 1.3.2 to 2.0.4 issue

Greetings! I'm currently using passkeys 1.3.2 in my project. However, when updating to the latest version 2.0.4, I encountered a backward compatibility issue on iOS, whereas Android functions as expected.

With passkeys registered under version 1.3.2, logging in using version 2.0.4 is not possible. Upon investigation, I discovered the following discrepancy:

  • Version 1.3.2 sends userHandle: NTkxMTE4, equivalent to 591118 in base64.
  • Version 2.0.4 sends userHandle: TlRreE1URTQ, which translates to NTkxMTE4 in base64, indicating that userHandle undergoes double encoding.

Is there a way to maintain the previous behavior to ensure the compatibility of passkeys saved by users?

androidx.credentials.TYPE_SECURITY_ERROR when using example app

Hey there, so I'm running in to an issue when running the example passkey native app in the repo on an android simulator. This is also the same as the error returned in my own application. Steps to reproduce:

  1. From packages/passkeys/passkeys directory, run melos run example-passkeys-native as instructed in the README
  2. Type in email address in the email address section
  3. click sign up

Returns error after a moment saying TYPE_SECURITY_ERROR The incoming request cannot be validated.

I have not modified any parts of the example application.

Check docs and examples

As we want to release a first version of our Flutter packages soon we need to make sure that our docs and examples are understandable and working.

We will release two packages:

  • passkeys (packages/passkeys): Allows you to build passkey register/login flows.
  • corbado_auth (passkeys/corbado_auth): Auth SDK that enables passkey based authentication. Handles persistent storage of tokens and refreshes (internally it uses the passkeys package).

For both of these packages we have a README.md (packages/passkeys/passkeys/README.md, packages/corbado_auth/README.md) and an example.

TODO:

  • Go through the README.mds and search for errors. Also check, how understandable they are. Feel free to add suggestions. I did not invest time in styling yet, so feel free to improvements here too.
  • Test if the two examples are working (ideally you test on an Android/iOS physical device and an Emulator/Simulator => 4 tests in total if you can test everything) => write down all errors that you encounter when testing these examples

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.