Skip to main content

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:

FeatureAndroidiOS
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:

  1. Security through the secure enclave and iCloud Keychain
  2. Consistent user experience across iOS applications
  3. 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

  1. Platform Awareness: Always handle the platform differences in your code
  2. Error Handling: Provide clear error messages when a feature is not available on a platform
  3. Fallback Mechanism: Offer alternative sign-in methods when a particular method fails
  4. Security First: Don't store passwords in your app's local storage or AsyncStorage
  5. Password Validation: Implement strong password requirements and validation
  6. 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:

  1. Detect Existing Authentication Methods: Check if the user has a password saved
  2. Offer Upgrade Path: Prompt users to create a passkey during login
  3. Gradual Transition: Allow both methods during a transition period
  4. Educational Material: Explain the benefits of passkeys to your users

Troubleshooting

Android Issues

  1. 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
  2. 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

  1. 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