Self Sign-Up
This walkthrough configures ThunderID so that new consumers can register themselves with an email and password. ThunderID creates a user record and returns the new user to your app signed in.
B2C Identity Overview covers the requirements story behind this use case.
Complete the Login walkthrough first. The user type, application, and sign-in flow set up there are required here.
Pick Your Pattern
Redirect-based
In the redirect-based pattern, your app redirects the user to ThunderID for the entire registration experience. After the user fills in the sign-up form, ThunderID creates the account and returns them to your app signed in.
Configure ThunderID
1. Build a registration flow
Build a REGISTRATION flow using the Flow Designer or the flows API. See Build a Flow.
Your registration flow should collect the user's credentials, provision the account, and return an auth assertion so the user lands signed in.
To automatically assign a default role to every self-registered user, create the role under Roles → Add Role. Then set properties.assignRole to that role's ID on the ProvisioningExecutor node in your flow. See Authorization.
Sample registration flow
{
"handle": "consumer-registration-flow",
"name": "Consumer Registration Flow",
"flowType": "REGISTRATION",
"nodes": [
{ "id": "start", "type": "START", "onSuccess": "user_type_resolver" },
{
"id": "user_type_resolver",
"type": "TASK_EXECUTION",
"executor": { "name": "UserTypeResolver" },
"onSuccess": "prompt_credentials",
"onIncomplete": "prompt_usertype"
},
{
"id": "prompt_usertype",
"type": "PROMPT",
"meta": {
"components": [
{ "align": "center", "type": "TEXT", "id": "heading_usertype", "label": "Choose your account type", "variant": "HEADING_1" },
{
"type": "BLOCK",
"id": "block_usertype",
"components": [
{ "type": "SELECT", "id": "usertype_input", "ref": "userType", "label": "Account type", "placeholder": "Select an account type", "required": true, "options": [] },
{ "type": "ACTION", "id": "action_usertype", "label": "Continue", "variant": "PRIMARY", "eventType": "SUBMIT" }
]
}
]
},
"prompts": [
{
"inputs": [ { "ref": "usertype_input", "identifier": "userType", "type": "SELECT", "required": true } ],
"action": { "ref": "action_usertype", "nextNode": "user_type_resolver" }
}
]
},
{
"id": "prompt_credentials",
"type": "PROMPT",
"meta": {
"components": [
{ "align": "center", "type": "TEXT", "id": "heading_credentials", "label": "Create your account", "variant": "HEADING_1" },
{
"type": "BLOCK",
"id": "block_credentials",
"components": [
{ "type": "TEXT_INPUT", "id": "input_username", "ref": "username", "label": "Username", "placeholder": "Pick a username", "required": true },
{ "type": "PASSWORD_INPUT", "id": "input_password", "ref": "password", "label": "Password", "placeholder": "Choose a password", "required": true },
{ "type": "ACTION", "id": "action_credentials", "label": "Continue", "variant": "PRIMARY", "eventType": "SUBMIT" }
]
}
]
},
"prompts": [
{
"inputs": [
{ "ref": "input_username", "identifier": "username", "type": "TEXT_INPUT", "required": true },
{ "ref": "input_password", "identifier": "password", "type": "PASSWORD_INPUT", "required": true }
],
"action": { "ref": "action_credentials", "nextNode": "credentials_auth" }
}
]
},
{
"id": "credentials_auth",
"type": "TASK_EXECUTION",
"executor": { "name": "CredentialsAuthExecutor" },
"onSuccess": "provisioning"
},
{
"id": "provisioning",
"type": "TASK_EXECUTION",
"executor": {
"name": "ProvisioningExecutor",
"inputs": [
{ "ref": "input_username", "identifier": "username", "type": "TEXT_INPUT", "required": true },
{ "ref": "input_password", "identifier": "password", "type": "PASSWORD_INPUT", "required": true }
]
},
"onSuccess": "auth_assert",
"onIncomplete": "prompt_schema_attrs"
},
{
"id": "prompt_schema_attrs",
"type": "PROMPT",
"meta": {
"components": [
{ "align": "center", "type": "TEXT", "id": "heading_schema_attrs", "label": "Tell us about you", "variant": "HEADING_1" },
{
"type": "BLOCK",
"id": "block_dynamic_user_inputs",
"components": [
{ "type": "DYNAMIC_INPUT_PLACEHOLDER", "id": "dynamic_inputs" },
{ "type": "ACTION", "id": "action_schema_attrs", "label": "Continue", "variant": "PRIMARY", "eventType": "SUBMIT" }
]
}
]
},
"prompts": [
{ "inputs": [], "action": { "ref": "action_schema_attrs", "nextNode": "provisioning" } }
]
},
{
"id": "auth_assert",
"type": "TASK_EXECUTION",
"executor": { "name": "AuthAssertExecutor" },
"onSuccess": "end"
},
{ "id": "end", "type": "END" }
]
}
2. Attach the registration flow to your application
Go to Applications → your app → Flows tab. Under Registration Flow, select the flow you created. Save the application.
See Manage Applications.
Integrate into Your App
Trigger sign-up from your app using the SDK. The registration experience is hosted by ThunderID, so your app only needs a sign-up entry point:
| Framework | Where to integrate |
|---|---|
| React | React Quickstart, <SignUpButton /> component |
| Next.js | Next.js Quickstart |
| Vue | Vue Quickstart |
| Browser SDK | Browser SDK Overview |
The redirect-based pattern is standard OAuth 2.0 authorization code flow with PKCE, so any OIDC-compliant SDK works. You are not limited to the ThunderID SDK. Point it at your ThunderID server's discovery endpoint (http://localhost:8080/oauth2/token/.well-known/openid-configuration) and use your Client ID from the registered application.
Try It Out
- Start your app and open it in the browser.
- Click your sign-up button. The browser navigates to ThunderID.
- Fill in a username, email, and password for a new user.
- Submit. ThunderID runs the registration flow, creates the user, and redirects back to your app.
- Verify that the new user lands in your app signed in.
App-native step-by-step
Coming soon. See the App-native pattern for what to expect.
App-native managed
Coming soon. See the App-native pattern for what to expect.
Direct API
Coming soon. See the Direct API pattern for what to expect.
Going Deeper
- Want to understand how user types and schemas work? See User Types in Identity Concepts.
- Want to automatically assign a role to self-registered users? See Roles in Identity Concepts.
- Want to see this use case running against the Wayfinder sample? See Self Sign-Up: Try It Out.