Password Authentication
This guide covers how to implement traditional username and password authentication in your React Native application using react-native-credentials-manager.
Platform Differences
Password authentication has important platform-specific differences you should understand:
Feature | Android | iOS |
---|---|---|
Manual Password Storage | ✅ Supported | ❌ Not supported |
AutoFill Password | ✅ Supported | ✅ Supported |
- Android: Uses the Credential Manager API to support both manual password storage and AutoFill integration
- iOS: Uses Authentication Services which only supports AutoFill passwords (via iCloud Keychain) and does not allow manual password storage
Manual Password Storage (Android Only)
Saving a Password
On Android, you can manually store a username and password:
import { signUpWithPassword, Platform } from "react-native-credentials-manager";
async function savePassword(username: string, password: string) {
if (Platform.OS === "android") {
try {
await signUpWithPassword({ username, password });
console.log("Password saved successfully");
} catch (error) {
console.error("Failed to save password:", error);
}
} else {
// iOS doesn't support manual password storage
console.log("Manual password storage not supported on iOS");
}
}
Why iOS Doesn't Support Manual Password Storage
Apple's Authentication Services framework doesn't provide an API for manual password storage. This is by design as Apple prioritizes:
- Security through the secure enclave and iCloud Keychain
- Consistent user experience across iOS applications
- Password AutoFill integration with Safari and iCloud Keychain
Instead, iOS apps should use the system's password AutoFill functionality.
Password AutoFill (Both Platforms)
Both Android and iOS support Password AutoFill through their respective platform APIs. This allows users to select saved passwords from their device's password manager.
Signing In with Password AutoFill
import { signIn } from "react-native-credentials-manager";
async function signInWithPassword() {
try {
const credential = await signIn(["password"], {});
if (credential.type === "password") {
const { username, password } = credential;
// Verify credentials with your backend
const loginResult = await yourBackendApi.login(username, password);
if (loginResult.success) {
console.log("Login successful");
} else {
console.error("Invalid credentials");
}
}
} catch (error) {
console.error("Password sign-in failed:", error);
}
}
Combined Authentication Methods
You can combine password authentication with other methods like passkeys or platform-specific sign-in:
import { signIn, Platform } from "react-native-credentials-manager";
async function signInWithMultipleMethods() {
try {
// Dynamically choose sign-in methods based on platform
const signInMethods = ["passkeys", "password"];
// Add platform-specific method
if (Platform.OS === "android") {
signInMethods.push("google-signin");
} else {
signInMethods.push("apple-signin");
}
const credential = await signIn(signInMethods, {
passkeys: {
challenge: "your-base64-challenge",
rpId: "yourdomain.com",
timeout: 60000,
userVerification: "required",
},
googleSignIn:
Platform.OS === "android"
? {
serverClientId: "your-web-client-id",
autoSelectEnabled: true,
}
: undefined,
appleSignIn:
Platform.OS === "ios"
? {
requestedScopes: ["fullName", "email"],
}
: undefined,
});
// Handle different credential types
switch (credential.type) {
case "password":
// Handle password credential
console.log("Password sign-in:", credential.username);
break;
case "passkey":
// Handle passkey credential
console.log("Passkey sign-in:", credential.authenticationResponseJson);
break;
case "google-signin":
// Handle Google sign-in
console.log("Google sign-in:", credential.idToken);
break;
case "apple-signin":
// Handle Apple sign-in
console.log("Apple sign-in:", credential.idToken);
break;
}
} catch (error) {
console.error("Sign-in failed:", error);
}
}
Password Storage and Security
Android
- On Android, passwords are stored in the Credential Manager encrypted storage
- The passwords can be synced across devices if the user has enabled Google Password Manager
- Biometric authentication can be required for accessing stored passwords
iOS
- On iOS, passwords are stored in the iCloud Keychain
- Passwords are securely synced across the user's Apple devices
- Password AutoFill is integrated with Safari's password management system
Best Practices
- Platform Awareness: Always handle the platform differences in your code
- Error Handling: Provide clear error messages when a feature is not available on a platform
- Fallback Mechanism: Offer alternative sign-in methods when a particular method fails
- Security First: Don't store passwords in your app's local storage or AsyncStorage
- Password Validation: Implement strong password requirements and validation
- Migration Path: Consider offering users a migration path from passwords to passkeys
Error Handling Examples
Here's how to handle potential errors during password operations:
import { signUpWithPassword, Platform } from "react-native-credentials-manager";
async function handlePasswordSignUp(username: string, password: string) {
if (Platform.OS !== "android") {
// Provide a clear message about platform limitations
return {
success: false,
error:
"Manual password storage is not supported on iOS. Please use another authentication method.",
};
}
try {
await signUpWithPassword({ username, password });
return { success: true };
} catch (error) {
// Handle specific error types
if (error.message?.includes("CANCELLED")) {
return {
success: false,
error: "Password save operation was cancelled by the user.",
};
} else if (error.message?.includes("NO_CREDENTIAL_AVAILABLE")) {
return {
success: false,
error: "No password credentials are available.",
};
}
// Generic error handling
return {
success: false,
error: `Failed to save password: ${error.message || "Unknown error"}`,
};
}
}
Transitioning from Passwords to Passkeys
As passkeys become more widely supported, you may want to help your users transition from passwords to passkeys. Here's a strategy:
- Detect Existing Authentication Methods: Check if the user has a password saved
- Offer Upgrade Path: Prompt users to create a passkey during login
- Gradual Transition: Allow both methods during a transition period
- Educational Material: Explain the benefits of passkeys to your users
Troubleshooting
Android Issues
-
Password Not Saved:
- Ensure the user didn't cancel the save operation
- Check if the app has the necessary permissions
- Verify the username and password fields are not empty
-
AutoFill Not Working:
- Ensure the user has saved passwords in their Google Password Manager
- Check if Google Play Services is up to date
- Verify your app is properly associated with your website
iOS Issues
- Password AutoFill Not Working:
- Verify your Associated Domains capability is properly configured
- Ensure your Apple App Site Association file is correctly set up
- Check if the user has saved passwords in iCloud Keychain
- Make sure your text input fields have the correct AutoFill type