List, Rename, Delete Passkeys
Users will need a way to create, view, and manage their passkeys after successfully registering a passkey with LoginID. Passkey management is important for security and user control. By listing, renaming, or deleting passkeys, users can:
- Keep their accounts secure by removing unused or compromised passkeys.
- Maintain clarity by renaming passkeys for easy identification.
There are two ways to access these passkey management methods:
- Using LoginID token from authenticated session with LoginID SDK
- Using an authorization token with backend integration
Prerequisites
- Create an application to obtain a base URL
- Create an API key with at least passkey:read, passkey:write, and reg:write scopes. (Only for backend integration method.)
Setup SDK
- Javascript
- Kotlin
- Swift
npm i @loginid/websdk3
Import and initialize an instance:
import { LoginIDWebSDK } from "@loginid/websdk3";
const lid = new LoginIDWebSDK({
baseUrl: process.env.LOGINID_BASE_URL,
});
Initialize a singleton configuration for the LoginID service in the application's onCreate
method.
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
// Initialize the singleton instance
val config = LoginIDServiceConfig("<BASE_URL>")
LoginID.configure(config).client()
}
}
Configure the singleton instance of LIDClient
with a base URL during the app's launch in the AppDelegate
.
import LoginID
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
// Initialize the singleton instance
LIDClient.shared.configure(baseURL: "<BASE_URL>")
return true
}
}
Examples
The code samples provided are for backend integrations using authorization tokens. Using the LoginID token's authenticated session does not require passing any tokens and can call the methods directly after a successful passkey authentication.
- List Passkeys
- Rename Passkey
- Delete Passkey
- Javascript
- Kotlin
- Swift
import { useAuth } from "../../contexts/AuthContext";
import { LoginIDWebSDK } from "@loginid/websdk3";
const config = {
baseUrl: BASE_URL,
};
const lid = new LoginIDWebSDK(config);
const PasskeyManagement: React.FC = () => {
const { user } = useAuth();
const [passkeys, setPasskeys] = useState([]);
useEffect(() => {
const run = async () => {
try {
// Get authorization token from your backend
// only if your backend is responsible for verifying user access.
// Passkey list
const _passkeys = await lid.listPasskeys({
authzToken: token,
});
setPasskeys(_passkeys);
} catch (e) {
if (e instanceof Error) {
setError(e.message);
}
}
};
run();
}, []);
};
import loginid.LoginID
import services.modals.LoginIDOptions
import services.modals.PasskeyInfo
class MainActivity : AppCompatActivity() {
private lateinit var errorTextView: TextView
private lateinit var passkeys: List<PasskeyInfo>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
errorTextView = findViewById(R.id.errorTextView)
handleListPasskeys()
}
private fun handleListPasskeys() {
val username = AuthContext.getUser().username
errorTextView.text = ""
GlobalScope.launch(Dispatchers.Main) {
try {
// Get authorization token from your backend
// only if your backend is responsible for verifying user access.
// Passkeys
val options = LoginIDOptions(token = token)
val _passkeys = LoginID.client().listPasskeys(options)
// Update UI with passkeys
passkeys = _passkeys
} catch (e: Exception) {
when (e) {
is LoginIDError -> {
errorTextView.text = e.message ?: "A LoginID error occurred"
}
else -> {
errorTextView.text = e.message ?: "An error occurred"
}
}
Log.e("Error", "An error has occurred", e)
}
}
}
}
Coming soon
- Javascript
- Kotlin
- Swift
import { useAuth } from "../../contexts/AuthContext";
import { LoginIDWebSDK } from "@loginid/websdk3";
const config = {
baseUrl: BASE_URL,
};
const lid = new LoginIDWebSDK(config);
const RenamePasskey: React.FC = () => {
const [error, setError] = useState<string>("");
const [passkeyName, setPasskeyName] = useState<string>("");
const [renameId, setRenameId] = useState<string>("");
const { user } = useAuth();
// Example of renaming a passkey
const handleRename = async () => {
try {
// Get authorization token from your backend
// only if your backend is responsible for verifying user access.
await lid.renamePasskey(renameId, passkeyName, { authzToken: token });
// Optionally refetch or update state data
// fetchPasskeys(token);
} catch (e) {
if (e instanceof Error) {
setError(e.message);
}
} finally {
setRenameId("");
setPasskeyName("");
}
};
};
import loginid.LoginID
import services.modals.LoginIDOptions
import services.BackendService
import services.AuthContext
class RenamePasskeyActivity : AppCompatActivity() {
private lateinit var errorTextView: TextView
private lateinit var renameId: String
private lateinit var passkeyName: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_rename_passkey)
errorTextView = findViewById(R.id.errorTextView)
// You would set renameId and passkeyName from user input or state
renameId = "passkeyIdToRename"
passkeyName = "NewPasskeyName"
handleRename(renameId)
}
private fun handleRename(passkeyId: String) {
GlobalScope.launch(Dispatchers.Main) {
try {
// Get authorization token from your backend
// only if your backend is responsible for verifying user access.
val options = LoginIDOptions(token = token)
LoginID.client().renamePasskey(passkeyId, passkeyName, options)
} catch (e: Exception) {
handleException(e)
} finally {
renameId = ""
passkeyName = ""
}
}
}
private fun handleException(e: Exception) {
when (e) {
is LoginIDError -> errorTextView.text = e.message ?: "A LoginID error occurred"
else -> errorTextView.text = e.message ?: "An error occurred"
}
Log.e("Error", "An error has occurred", e)
}
}
Coming soon
- Javascript
- Kotlin
- Swift
import { LoginIDWebSDK } from "@loginid/websdk3";
const config = {
baseUrl: BASE_URL,
};
const lid = new LoginIDWebSDK(config);
const DeletePasskey: React.FC = () => {
const [error, setError] = useState<string>("");
const [passkeyId, setPasskeyId] = useState<string>("");
// Example of deleting a passkey
const handleDelete = async () => {
try {
// Get authorization token from your backend
//only if your backend is responsible for verifying user access.
await lid.deletePasskey(passkeyId, { authzToken: token });
// Optionally refetch or update state data
// fetchPasskeys(token);
} catch (e) {
if (e instanceof Error) {
setError(e.message);
}
} finally {
setPasskeyId("");
}
};
};
import loginid.LoginID
import services.modals.LoginIDOptions
import services.BackendService
class DeletePasskeyActivity : AppCompatActivity() {
private lateinit var errorTextView: TextView
private lateinit var passkeyId: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_delete_passkey)
errorTextView = findViewById(R.id.errorTextView)
// You would set passkeyId from user input or state
passkeyId = "passkeyIdToDelete"
handleDelete(passkeyId)
}
private fun handleDelete(passkeyId: String) {
GlobalScope.launch(Dispatchers.Main) {
try {
// Get authorization token from your backend
// only if your backend is responsible for verifying user access.
val options = LoginIDOptions(token = token)
LoginID.client().deletePasskey(passkeyId, options)
// Optionally update UI
} catch (e: Exception) {
handleException(e)
}
}
}
private fun handleException(e: Exception) {
when (e) {
is LoginIDError -> errorTextView.text = e.message ?: "A LoginID error occurred"
else -> errorTextView.text = e.message ?: "An error occurred"
}
Log.e("Error", "An error has occurred", e)
}
}
Coming soon