f-23 / react-native-passkey Goto Github PK
View Code? Open in Web Editor NEWPasskeys for React Native
License: MIT License
Passkeys for React Native
License: MIT License
[IOS] Is there any way to specify available transports for a key and sort keys by excludecredentials ?
When running the example I get the error message {"error": "InvalidChallenge", "message": "The provided challenge was invalid"}
Not sure why, and if i then set the challange to test for instance I get {"error": "RequestFailed", "message": "The request failed. No Credentials were returned."}
Hi, I am executing a demo with this library using fido2-lib
on the backend with mocked data. I have the assetlinks.json
and the apple-app-site-association
and the devide is aking me to generate or use passkey when i press the buttons that execute the methods this library is providing so everything seems to be working fine but I have one question regarding the origin
this library provides in the result returned by the methods.
The registrationRequest the library is using, given by the fido2-lib
's method attestationOptions
contain the following information:
{
rp: {
name: 'My web',
id: 'my-web.com'
},
user: {
id: 'someId',
name: 'User Name',
displayName: 'Display User Name'
},
challenge: 'challenge_properly_formed',
pubKeyCredParams: [
{ type: 'public-key', alg: -7 },
{ type: 'public-key', alg: -257 },
],
timeout: 10000,
attestation: 'direct',
authenticatorSelection: {
authenticatorAttachment: 'platform',
requireResidentKey: true,
userVerification: 'required'
}
}
On iOS, the PasskeyRegistrationResult
the library is returning provided me the following clientDataObj
:
{
type: 'webauthn.create',
challenge: 'challenge_properly_formed',
origin: 'https://my-web.com'
}
https://my-web.com
is a backend serving the android and ios files properly.
apple-app-site-association
{
webcredentials: {
apps: ['value.com.org.package']
}
}
assetlinks.json
[
{
relation: ['delegate_permission/common.handle_all_urls', 'delegate_permission/common.get_login_creds'],
target: {
namespace: 'android_app',
package_name: 'com.org.package',
sha256_cert_fingerprints: ['HEX_VALUE']
}
}
]
So when i compare this info against what my backend should have everything works fine. The fido2-lib
method is working:
const expectedAttestationResult: ExpectedAttestationResult = {
challenge: 'challenge_properly_formed',
origin: 'https://my-web.com',
factor: 'first'
}
const attestationResult: Fido2AttestationResult = await f2l.attestationResult(
clientAttestationResult,
expectedAttestationResult
)
However, on android, the library returns the following clientDataObj
:
{
type: 'webauthn.create',
challenge: 'challenge_properly_formed',
origin: 'android:apk-key-hash:HASH',
androidPackageName: 'com.org.package'
}
The attestationResult
method returns Error: clientData origin did not match expected origin
.
I know this might be more on the fido2-lib
side of things, and i will ask them too but, is the PasskeyRegistrationResult
returned by the library on android the way it should be? Is the library getting the info about the origin from those files served by the backend?
Hey there,
Nice job, I like your module.
I've seen in the file 'react-native-passkey/ios/Passkey.swift',
You check if Passkeys are supported by the OS version, if not, you return an error message. I think that part is right.
But, it appears that you are requesting a minimum deployment target of 15 in your pod specification.
=> CocoaPods failed to find a compatible version for pod "react-native-passkey" if your project minimum deployment target is less than 15.
For your module to be usable in apps that are currently in production, you should reduce the minimum deployment target to at least 11 or 12.
Function PasskeyAndroid.register
transforms the returned credentialId
from base64url to base64:
/**
* Transform the attestation or assertion result
*/
private static handleNativeResponse(
response: PasskeyRegistrationResult & PasskeyAuthenticationResult
): PasskeyRegistrationResult & PasskeyAuthenticationResult {
// Transform Base64URL Response to Base64
let id = response.id;
if (id.length % 4 !== 0) {
id += '==='.slice(0, 4 - (id.length % 4));
}
id = id.replace(/-/g, '+').replace(/_/g, '/');
return {
...response,
id,
rawId: id,
};
}
}
When this credentialId
is used later in authenticate
, it's still transformed to base64
format while android expects base64url
. Android fails to decode the credentialId if it ends with ==
:
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: ebyf: java.lang.IllegalArgumentException: bad base-64
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at baoi.apply(:com.google.android.gms@[email protected] (190408-577232161):43)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at ebua.d(:com.google.android.gms@[email protected] (190408-577232161):3)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at ebub.run(:com.google.android.gms@[email protected] (190408-577232161):139)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at ajlc.c(:com.google.android.gms@[email protected] (190408-577232161):50)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at ajlc.run(:com.google.android.gms@[email protected] (190408-577232161):76)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at ajqf.run(:com.google.android.gms@[email protected] (190408-577232161):8)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at java.lang.Thread.run(Thread.java:1012)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: Caused by: java.lang.IllegalArgumentException: bad base-64
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at android.util.Base64.decode(Base64.java:163)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at android.util.Base64.decode(Base64.java:138)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at android.util.Base64.decode(Base64.java:120)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialDescriptor.b(:com.google.android.gms@[email protected] (190408-577232161):15)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialRequestOptions.a(:com.google.android.gms@[email protected] (190408-577232161):94)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at udq.a(:com.google.android.gms@[email protected] (190408-577232161):14)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at baog.a(:com.google.android.gms@[email protected] (190408-577232161):7)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at ebug.d(:com.google.android.gms@[email protected] (190408-577232161):3)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: at ebui.run(:com.google.android.gms@[email protected] (190408-577232161):42)
11-06 11:48:26.170 12673 13701 W Auth.Api.Credentials: ... 6 more
And returns error:
11-06 11:48:26.187 13250 13388 I ReactNativeJS: [login error]: Error: [checkSignatureIsValid]: Error: [Passkey authentication error]: {"error":"NoCredentials","message":"No viable credential is available for the user."}
Possible fixes: Return rawId with value returned by platform to use it in authenticate
. Add base64 to base64url credentialId transformation based on current platform in authenticate
Hey sorry for the bad issue not sure where else to ask.
I am not sure from the docs what the format for the challenge should be?
I have tried using the sample challenge from the server response in the fido2-lib but still I get logs like:
Error: {"error": "InvalidChallenge", "message": "The provided challenge was invalid"}
I understand you guys are wrapping some native modules, is there some docs for those that I could reference? Or maybe you could link to them in the readme?
Hi!
I'm using the lib on my app, it worked perfectly until i've added a fingerprint (and then deleted) in my Android phone. Since the passkey registration don't show again (and yes it's still supported and it seems to be working on Login).
There isn't any much logs either a part from "Unknown error"
Any idea how i can increase the error logs ? or to understand why when i've added a fingerprint on my phone the passkey don't show up ? Is there a security level that need to be implemented ?
Thanks
I'm seeing an error when importing/requiring this module after installation where the file linked in mail does not exist.
What's the proper way to import this module after installation?
Context:
In package.json the react-native
property is set to src/index
which is not found on the npm distributed package. When changing that to lib/module/index
all works just fine. Should that change be in the npm package or I'm importing it wrong?
Here's the error and the screenshot
error: Error: While trying to resolve module `react-native-passkey` from file `<masked_path>`, the package `<masked_path>mobileapp/node_modules/aws-cognito-passwordless/client/node_modules/react-native-passkey/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`<masked_path>mobileapp/node_modules/aws-cognito-passwordless/client/node_modules/react-native-passkey/src/index`. Indeed, none of these files exist:
* <masked_path>mobileapp/node_modules/aws-cognito-passwordless/client/node_modules/react-native-passkey/src/index(.native|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
* <masked_path>mobileapp/node_modules/aws-cognito-passwordless/client/node_modules/react-native-passkey/src/index/index(.native|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
at DependencyGraph.resolveDependency (<masked_path>mobileapp/node_modules/metro/src/node-haste/DependencyGraph.js:277:17)
at Object.resolve (<masked_path>mobileapp/node_modules/metro/src/lib/transformHelpers.js:170:21)
at resolveDependencies (<masked_path>mobileapp/node_modules/metro/src/DeltaBundler/graphOperations.js:466:33)
at processModule (<masked_path>mobileapp/node_modules/metro/src/DeltaBundler/graphOperations.js:232:31)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async addDependency (<masked_path>mobileapp/node_modules/metro/src/DeltaBundler/graphOperations.js:361:18)
at async Promise.all (index 6)
at async processModule (<masked_path>mobileapp/node_modules/metro/src/DeltaBundler/graphOperations.js:279:3)
at async addDependency
Hey @f-23, thanks for the lib.
Is there an API for checking if passkeys are supported on the customer device?
Hi there, I am planing on uses passKeys to store some data in the largeBlob which was recently added in ios 17. (WebAuthn Large Blob Extension) Any plans of implementing this ? I am trying to do it myself, but have never used swift before.
Mfg Ronald
Hello,
I'm currently integrating this library into my React Native application to enable passkey functionality. I have followed all the configuration steps outlined in the README.md, including setting up the associated domain and other relevant settings.
The implementation works flawlessly on iOS (version 17.2), where the passkey creation and usage are functioning as expected. However, I am encountering a problem on the Android platform. Despite a successful build and the appearance of the passkey creation popup on Android, an error occurs during the registration process. The error message is as follows:
{
"error": "Native error",
"message": "androidx.credentials.exception.CreateCredentialCustomException:"
}
This issue is puzzling, as it seems to be specific to the Android environment, and I'm unsure of the underlying cause. I would greatly appreciate any insights or suggestions on what might be leading to this error. Could there be a step I'm missing, or is it potentially a bug within the library when used on Android?
Thank you in advance for your assistance and guidance. ๐
Hey! I'm using react-native-passkey and works great. I recently migrated to v2.0, and I've noticed some types are now just object
, like here
Previously I remember was typed. I'm wondering if this is intentional! Otherwise, I'm happy to push a PR.
Cheers
Hello,
It seems that the library is transforming the base64Url into a base64. I wonder why? Since most data are JWTs, this makes them incorrect and doesn't work with some authentication systems.
Could there be an option to get the base64url content?
When react native newArchEnabled flag is enabled (https://reactnative.dev/docs/the-new-architecture/why) library fails with error
Error is Error: ENOENT: no such file or directory, lstat '/Users/andrey/projects/xraise mobile/node_modules/react-native-passkey/src'
For some reason rn looks for node_modules/react-native-passkey/src
instead of node_modules/react-native-passkey/android/src
React native migration guides do not help. Seems that something is wrong with library
Hello,
I am currently working with the iOS system sheet controlled by the withSecurityKey
boolean variable. As it stands, there is no option to switch between using a passkey or a security key once the ASAuthorizationController
is initiated. This limitation restricts the flexibility needed for a more dynamic authentication process.
I propose an enhancement where ASAuthorizationController
can be initialized with multiple requests, allowing users to switch between authentication methods directly from the system sheet. Enabling this feature would activate the "Other Sign in Options" button on the sheet, providing users the ability to change their request method on the fly.
The desired implementation could look something like this:
let securityKeyProvider = // existing security key provider
let platformKeyProvider = // existing platform key provider
let controller = ASAuthorizationController(authorizationRequests: [platformKeyProvider, securityKeyProvider])
In a JavaScript context, the usage could be as follows:
register(request) // Default to exposing only passkey.
register(request, ['passkey']) // Expose only passkey.
register(request, ['securitykey']) // Expose only security key.
register(request, ['passkey', 'securitykey']) // Initially expose passkey with an option for security key under "Other Sign in Options".
register(request, ['securitykey', 'passkey']) // Initially expose security key with an option for passkey under "Other Sign in Options".
This feature would greatly enhance the user experience by providing more flexibility and control over the authentication process. Could you please consider supporting this functionality?
Thank you for your time and consideration.
Need to add support for physical keys on iOS.
Add support for Android. Since there is no native API for passkeys available on Android a possible workaround would be to use a web view and authenticate with the server through it.
Thanks for the great library. There is a lot going on here, trying to understand all the pieces that are necessary!
?mode=developer
at the end)Desperately trying to integrate this locally (on iOS simulator), and keep running into the same issue: "An unknown error occurred". Despite this, if I create a release build I am able to use the library.
Mac Console
has some interesting messages from the simulator:
ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "(null)"
Could not perform authorization: Error Domain=com.apple.AuthenticationServicesCore.AuthorizationError Code=1 "(null)"
Device not configured for passkey requests: Error Domain=com.apple.LocalAuthentication Code=-7 "(null)"
I am working on a React Native application and am trying to support the Fido2 auth standard. I believe I have the server side configured correctly with AWS, however, when I call Passkey.register() I keep getting a really obscure error:
Object {
"error": "RequestFailed",
"message": "The request failed. No Credentials were returned.",
}
I am using version 2.0.0 of this library. Is there a way to tell what is causing the issue such as a way to confirm my challenge is formatted correctly? Is there a specific simulator version I need to use for testing? I'm stuck on troubleshooting next steps as all my attempts are starting to go in circles and keep leading me back to this vague error message.
hi @f-23, thanks for creating this great RN library. I'm trying the example on my Android device (Samsung A53). I'm able to create account and get a valid registration result but when I try to authenticate. This error occur:
{"error": "NotCredentials", "message": "No viable credential is available for the the user."}
I am using the same RegRequest.json and AuthRequest.json, only modified the rp id. The allowCredentials in AuthRequest is keeping an empty array. Is there any param in registration or auth request can cause the problem? any suggestion is appreciated.
Thanks,
Hey, not really an issue but more of a clarifying question since I think this library is going to become really important as passkeys gain steam.
My team recently built an ios, android, web, and backend implementation for passkeys separately, and the most challenging part was making sure the format of the result (like the register or auth result) matched up with what the webauthn server was expecting. We used Yubico as a starting point i believe and, for example, on ios i needed to do a lot of base64url converting (and back) and making sure that all properties of the result objects were there. the web has https://github.com/github/webauthn-json to ensure the format is correct, but had to do it manually for ios and android.
So my question is, should the handoff between client and sever be the responsibility of the developer? or should this library be more opinionated in this and add suggest a specific server?
trying to add passkey to our application but encounting errors, so tried example and all ive got is (same as mine tests)
LOG {"error": "Native error", "message": "androidx.credentials.exceptions.domerrors.SecurityError@1469d41"}
LOG {"error": "Native error", "message": "androidx.credentials.exceptions.domerrors.SecurityError@1469d41"}
LOG {"error": "Native error", "message": "androidx.credentials.exceptions.domerrors.SecurityError@1469d41"}
LOG {"error": "Native error", "message": "androidx.credentials.exceptions.domerrors.SecurityError@1469d41"}
LOG {"error": "Native error", "message": "androidx.credentials.exceptions.domerrors.SecurityError@1469d41"}
LOG {"error": "Native error", "message": "androidx.credentials.exceptions.domerrors.SecurityError@1469d41"}
test device: moto g72 / android 13
Add passkey web support for full cross-platform compatibility.
Hi there,
First of all, thank you very much for developing this in such a short time since APIs are released, it definitely has a long life to live!
I was trying it today on an expo-based app and I had issues directly after installing the library. Of course, I didn't do the pod install since it's an Expo Go managed project, this is the error I got:
Would that be added in the near future?
Thanks.
Eric.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.