Handle Multiple Workflows
For processes that require more than one step, such as logging in and then signing a contract, you can chain multiple authentication workflows together. The did-auth library facilitates this by allowing one completed workflow to trigger the next, seamlessly passing data between them.
This is managed by returning nextWorkflow, nextToken, and optionally nextWorkflowData from the onAuth callback upon the successful completion of a step.
Authentication Flow#
The following diagram illustrates the sequence of a two-step authentication process where Workflow A is followed by Workflow B.
How It Works#
The process relies on a few key properties that you return from your onAuth handler.
Property | Description |
|---|---|
| The full DID Connect URL for the next authentication step. The wallet will automatically proceed to this URL. |
| The session token for the |
| An object containing any data you want to pass from the current workflow to the next one. |
| This data is available in the |
When nextWorkflow is returned, the library links the current session to the next one. Upon completion of the final workflow in the chain, all preceding linked sessions are automatically marked as succeed.
Implementation Example#
To implement a multi-step workflow, you'll primarily use the onAuth callback to control the flow.
In this example, the first step authenticates the user (an authPrincipal claim), and the second step asks for their profile information.
// did-auth handler setup
handlers.attach({
app: server,
action: 'multi-step-demo',
claims: [
{ // This is the claim for the *second* step
profile: () => ({
fields: ['fullName', 'email'],
description: 'Step 2: Provide your profile',
}),
},
],
onAuth: async ({ claims, extraParams }) => {
// Check if we are in the first step (authPrincipal claim)
// The `previousWorkflowData` will be absent in the first step.
const isFirstStep = claims.length === 0;
if (isFirstStep) {
console.log('Step 1 (Login) complete. Starting Step 2 (Profile).');
// Generate a new token and URL for the next workflow step
// Note: This assumes you have an endpoint to generate a new session.
const { data: nextStepInfo } = await axios.get(`${server.url}/api/did/multi-step-demo/token`);
return {
nextWorkflow: nextStepInfo.url, // URL for the wallet to continue
nextToken: nextStepInfo.token, // Session token for the next step
nextWorkflowData: { step: 1, message: 'Login successful!' }, // Data to pass
};
}
// This is the second step, because previousWorkflowData exists
console.log('Step 2 (Profile) complete.');
console.log('Data from Step 1:', extraParams.previousWorkflowData);
// Expected output: { step: 1, message: 'Login successful!' }
const profile = claims.find((x) => x.type === 'profile');
console.log('User profile:', profile);
return { successMessage: 'Multi-step process finished!' };
},
});Data Flow Between Steps#
- After the user completes the first authentication step, your
onAuthhandler returns thenextWorkflowdetails. The library serializesnextWorkflowDatainto thenextWorkflowURL that is sent to the wallet.
Response to Wallet (after step 1):{
"status": "ok",
"response": {
"nextToken": "f2c4e1a3",
"nextWorkflowData": {
"step": 1,
"message": "Login successful!"
}
},
"nextWorkflow": "https://abtwallet.io/i/?url=https%3A%2F%2Fexample.com%2Fapi%2Fdid%2Fmulti-step-demo%2Fauth%3F_t_%3Df2c4e1a3%26previousWorkflowData%3DeyJzdGVwIjoxLCJtZXNzYWdlIjoiTG9naW4gc3VjY2Vzc2Z1bCEifQ"
} - The wallet proceeds to the
nextWorkflowURL. When the user approves the second claim, youronAuthhandler is called again. This time, theextraParamsobject contains thepreviousWorkflowDatafrom the first step.extraParamsinonAuth(during step 2):{
// ... other params
previousWorkflowData: {
step: 1,
message: 'Login successful!'
}
}
Chaining More Than Two Workflows#
The library automatically merges workflow data. If you chain three workflows (A → B → C):
- Workflow A passes
nextWorkflowDatato B. - When B completes, it can return its own
nextWorkflowData. The library merges this new data with the data received from A. - The combined data object is passed to workflow C as
previousWorkflowData.
By returning nextWorkflow from your onAuth handler, you can create sophisticated, multi-step user experiences. This is ideal for scenarios like progressive onboarding or multi-part transactions.
To see how this can be applied, continue to the Request a Signature guide to learn how to ask for a signature after a user has logged in.