Implement Dynamic Claims
In some authentication scenarios, the claims you need to request from a user are not static. You might need to ask for different information based on the user's identity, their permissions, or other contextual data available at runtime. The did-auth library supports this through a powerful feature: dynamic claims.
This guide explains how to use the onConnect callback to generate claim requests on-the-fly for each authentication session.
The onConnect Callback#
The primary mechanism for implementing dynamic claims is the onConnect callback function, which you can provide when setting up your authentication routes with walletHandlers.attach.
This function is executed every time a wallet initiates a connection to an authentication endpoint. It runs before the claims are finalized and sent to the user's wallet, giving you a hook to inject or modify the claim requests for that specific session.
How It Works#
Here is a diagram illustrating the sequence of events when onConnect is used:
How to Implement Dynamic Claims#
Follow these steps to add dynamic claims to your authentication flow.
1. Define the onConnect Callback#
First, create a function that returns an array of claim definition objects. Each object specifies a claim your application wants to request. The claims themselves can be defined as functions to be resolved later.
// This function will be called for each new session
const generateDynamicClaims = () => {
// You can add logic here to decide which claims to return
console.log('Generating claims for a new connection...');
// Return an array of claim objects.
// In this case, we are dynamically requesting a user's profile.
return [
{
profile: () => ({
fields: ['fullName', 'email'],
description: 'Please provide your name and email for registration.',
}),
},
];
};2. Attach the Handler with onConnect#
Next, pass your onConnect function when you attach the handlers for a specific action. The WalletHandlers will automatically execute this function at the appropriate time in the authentication flow.
const { WalletHandlers } = require('@arcblock/did-auth');
// Assuming 'handlers' is an instance of WalletHandlers and 'server' is an Express app
handlers.attach({
app: server,
action: 'dynamic_login',
onConnect: generateDynamicClaims, // Pass your function here
onAuth: async ({ claims }) => {
// Handle the claims returned by the user
console.log('User submitted claims:', claims);
return { successMessage: 'Login successful!' };
},
});In this example, every time a user starts the dynamic_login flow, the generateDynamicClaims function runs and instructs the wallet to request the user's profile.
Advanced Usage: Context-Aware Claims#
The onConnect callback is executed with the Express req, res, and session objects as arguments. This allows you to create sophisticated, context-aware logic.
For example, you could check for a cookie or a query parameter to decide whether to request an additional, more sensitive claim.
const onConnectWithContext = (req, res, session) => {
const claims = [
{
profile: () => ({
fields: ['fullName'],
description: 'Please provide your full name.',
}),
},
];
// Check if the user is part of a beta program, indicated by a query parameter
if (req.query.beta_access === 'true') {
claims.push({
asset: () => ({
description: 'Please present your Beta Access Pass',
// Add filter criteria for the asset if needed
}),
});
}
return claims;
};
handlers.attach({
app: server,
action: 'context_login',
onConnect: onConnectWithContext,
onAuth: async ({ claims }) => {
// ...
},
});What's Next?#
Now that you know how to request claims dynamically, you may want to:
- Explore all available claim types in Understanding Claims.
- Chain multiple authentication steps together by learning how to Handle Multiple Workflows.