Create Passkey Over Authorized Session
This flow applies to scenarios such as:
-
Post sign-up/onboarding completion. Passkeys are created after successful onboarding, ensuring users meet verification requirements, reinforcing security right from the start.
-
Users in a pre-authenticated session. This ensures users are authenticated or pre-approved by your server before registering, preventing unauthorized access and ensuring only legitimate users can create a passkey.
To protect the passkey creation process, ensure you have an authorized session by using API keys to request authorization tokens, which are passed to LoginID client SDKs.
This flow applies when your LoginID application is classified as a protected application, meaning that Registration Requires Authentication Token is enabled in your application settings.
When this setting is enabled, users must be authenticated or pre-authorized. This ensures that only verified users can create accounts and generate passkeys, requiring a valid authorization token during the registration process.
Overview Diagram
This high-level sequence diagram outlines the process:
- Finalized user onboarding or pre-authenticated session.
- Your backend requests an authorization token from LoginID by calling POST /fido2/v2/mgmt/grant authorized with your API key with the scope passkey:write.
- The token is passed to the LoginID client SDK to execute client.createPasskey(username, token).
- The token authorizes the creation of the passkey with LoginID.
Here is an example of how it might look like:
Prerequisites
- Create an application to obtain a base URL
- Create an API key with at least passkey:read, passkey:write, and reg:write scopes
- Make sure your application's register APIs are secure
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
}
}
Create Passkey
After obtaining the authorization token from your backend, pass it to the LoginID client SDK. The user creates a passkey, and the response includes a LoginID token.
- Javascript
- Kotlin
- Swift
import { useAuth } from "../../contexts/AuthContext";
import { LoginIDWebSDK } from "@loginid/websdk3";
const lid = new LoginIDWebSDK({
baseUrl: process.env.REACT_APP_LOGINID_BASE_URL,
});
const Register: React.FC = () => {
const [username, setUsername] = useState<string>("");
const [error, setError] = useState<string>("");
const { setAuthUser } = useAuth();
const handleRegister = async (e: React.FormEvent) => {
e.preventDefault();
try {
// Get the authorization token from your backend after a successful onboarding
// or pre-authenticated session
// User creates a passkey
const { token } = await lid.createPasskey(username, authzToken);
// You can return LoginID token to your backend for verification
setAuthUser(user);
} catch (e) {
if (e instanceof Error) {
setError(e.message);
}
}
};
};
import loginid.LoginID
import services.modals.LoginIDOptions
class MainActivity : AppCompatActivity() {
private lateinit var usernameEditText: EditText
private lateinit var errorTextView: TextView
private lateinit var registerButton: Button
private fun handleRegister() {
val username = usernameEditText.text.toString()
errorTextView.text = ""
GlobalScope.launch(Dispatchers.Main) {
try {
// Get the authorization token from your backend after a successful onboarding
// or pre-authenticated session
// User creates a passkey
val options = LoginIDOptions(token = authToken)
val result = LoginID.client().registerWithPasskey(this@MainActivity, username, options)
// You can return LoginID token to your backend for verification
AuthContext.setAuthUser(user)
} catch (e: Exception) {
when (e) {
is LoginIDError -> {
errorTextView.text = e.message ?: "A LoginID error occurred"
}
else -> {
errorTextView.text = e.message ?: "An error occurred"
}
}
}
}
}
}
Coming soon
Once you have received the result LoginID token, you can send it to your backend, and verify it. For detailed technical instructions, refer to this section on verifying LoginID tokens.