workflow for self registration
-
Thanks to your help, I managed to get the passwordless login working from PHP. All kudos to you!
I have one more task to accomplish. Users will be able to register themselves. Here is the flow as I see it:
- user fills out registration form in my application
- if their email is unique, FA will send a verification email
- user will verify and I will register them in FusionAuth
The steps that are new to me are the a) send verification email b) register the user (with logging them in)
Do you have a workflow for this via the API? I am don't want to add them into FA until they have verified their email address. I am not sure what steps I need to take to get the verification email to be sent?
Thanks.
-
In looking through the docs i see:
POST /api/email/send/{emailTemplateId}
I'd like to use this to send an email to a person trying to register. The only question is that userId is required.
userIds [Array<UUID>] REQUIRED
The list of User Ids to send the Email to. You must specify at least one Id.Problem: I don't have a userId (for this person) yet since I haven't added this person to FA yet. So I suspect that there is a step I need to do before I send this email to verify their email address? What is that function call?
-
I suppose that you are again confusing applications registrations with user account creation. So I will assume that you mean the latter.
FA supports such feature out of the box, but the flow is a bit different:
- User account is being created. It fails if the user email is invalid or not unique. Starting from here, the account exists, but is marked as not verified.
- FA sends email verification email. After visiting the verification link, the user will be marked as verified.
- Optionally, if the verification link is not visited for some time, FA can automatically delete the account.
So using built in features there is no easy way to implement the exact feature you are asking for. But you can block application access for users marked as unverified in your application, which supposedly fulfills your higher level requirement.
The functionalities I've described are configurable in the Edit Tenant > Email settings
-
Thanks. That sounds like a plan. The only question is "if the email is not verified, how will my app know that", so i can delete the "ALMOST" user from the apps database (not FA's).
-
I believe that
user.delete
webhook is being called on an event of automatic unverified user deletion, so you should be able to utilize it for external resources synchronization. -
@mgetka Thank you. That is helpful. I have two different tenants. One is called default and that is used for passwordless login (PLI) A and works fine. I have another called administrators (PLI B) that i am trying to get working now.
Here is an image of the home/tenants and you can see Default and administrators. Default is for PLA and administrators is for PLI B.
Now here are my Home/applications. Notice that under Toolkit Administrators the tenant is set to Default. I'd like to set that to administrators.
I realize that FA has a built in registration verification, but I didn't use it. This is mostly due to the fact that i am developing under docker on my laptop so I really can't use localhost (from the outside world) to respond to FA emails. Anyway, I can't seem to change the Tenant for the administrator application. It's tooltip displays "read only". How can I change the application "Toolkit Administrators" tenant to administrators?
-
There is no way to transfer an application from one tenant to another. You must create new application in the second tenant.
You may help yourself with applications API to get json representation of your app, tweak it as needed, and post in another application creation request.
Going back to the original question and external resources synchronization. You may also populate your external database only once the user verifies his email.
user.email.verified
webhook event can be utilized for such solution. -
@mgetka said in workflow for self registration:
You may also populate your external database only once the user verifies his email. user.email.verified webhook event can be utilized for such solution.
Good point. However I save the record number in the id field (of my table) of FA. That allows me to directly get to the record to delete the record, if need be. And I don't have the record number (to pop into the FA table) until I do an INSERT into my table.
The problem I am having is that I register the administrator, but registration-verification email is not being sent. Here is what I am doing:
I register an admin with $result = $_SESSION['client']->register("", $requestJ);
I do have Self Service Registration enabled.
For the Verification Template I have set it to Registration Verification.
So I expected FA to send that verification email out by itsef, but that is not what is happening. I has assumed that this was because I have the tenent for this workflow set to Default. But I really don't need the tenant at all.
Any idea why the verification email is not being sent? -
I believe you are again confusing user creation with registrations. Please refer to the docs for better understanding of the differences.
To sum it up, user entity, created on an user creation event represents an user. This entity contains the user email and its verification status. The user email verification email may be sent only on user creation.
The registration, is an entity that associates already existing user to a specific application. The registration is not related to user email nor its verification status. However, it can contain alternative username to be used by the user in this application only. On an event of registration creation, FA can send confirmation email, but it doesn't confirm user email, it only confirms whether the registration of an user in the application should persist.
You are quoting a code snippet with a
register
API request, so I suppose you are actually attempting on registration creation, having user creation in mind. The quoted request itself is invalid - the first argument should contain UUID of the user (since registrations are created for users that already exists) so it cannot be successful. This may be the cause of not receiving any emails. If not, you may check your SMTP settings in the tenant configuration. SMTP related errors can also be tracked via System > Event Log. -
@mgetka OK. The nomenclature is getting clearer. You are saying that the word "registration" only goes with an application and the word "create" only goes with a user.
In my case I have "registered" the application through the UI. My code is just fiddling with "creation" of users. It does no registering of applications.
Now when I run my code, it does create a user (I know because i can see them in the UI). But I will fix this. So clearly I don't want to use "register" a to add a user (to an already existing application). There must be some other php call to add a new user to an existing application? which?
Looking at the Docs under Core Concepts/Users I see this:
User scope
A User is scoped to a Tenant. A User existing within a Tenant can be registered to, and use the same credentials to authenticate to multiple applications within that Tenant.In fact I just searched for the word "create" on that page and it doesn't exist other than in "user action API". I then did a search on all the docs and can find the word "create" but not associated with a "user". Is the term "user action" synonymous with "create user"?
I then found this is the Docs:
Registrations
A User can be registered to one or more FusionAuth Applications. A User Registration can define one to many Application Roles.As you can see from the above statement, a User gets "registered" to a FA application. This is actually what i am trying to do since the application already exists (I created it in the UI).
I am trying to find a function in the php-client that will create a "user entity". My SMTP is fine. One more thing. Am I correct to assume that a verification email will be sent automatically upon a user action to create a user (once I get that going)?
-
Well, somehow I got it working. Thx for your help. The verification email is being sent and the user can verify.
I want to set the time allowed for a user to verify to about 5 minutes. At that point I'd like to delete the user from FA and fire off a webhook that will tell my application to delete the user from my apps user table.
Where can I set a timer for the verification to be complete? Or does my app need to watch the time and then send a user delete to FA?
-
I'm glad you got it working! Finishing the topic I will leave few more links:
There is also combined API call, that creates a user and a registration at once - I have missed that saying your register request is invalid - sorry. User creation and registration in one call. This is probably the request you were trying to perform.
You can configure unverified users deletion time in Edit Tenant > Email - as mentioned in my first response. But 5 minute offset is not reachable since the time is given in days.
-
Thanks again. As I think i said i have two different passwordless logins (type A and type B). Type A is for a user to take a survey. Type B is for an administrator to register themselves. For type A I am using Tenant default. In this under Template settings I have my Passwordless login template.
Now for type B I want to have a completely different Passwordless login template (it will say different stuff). But I see under Tenant Default there is only a place for one passwordless login template.
Now I have two different applications,type A (which uses tenant default) and type B (which also uses tenant default)? Why? Because the tenant field in Applications is read only.
You mentioned a day or two ago creating an application under the 2nd tenant. How do I do this in the UI? Under Tenant, is there a place for me to specify what Application to use?
I am thinking that the easiest way to do this would be to just create another application, so there will be 3 in total. But how to create it under it's own tenant (in the UI)?
-
But how to create it under it's own tenant (in the UI)?
Once you have more than one tenant, you should see a dropdown when you are adding an application in the UI which lets you determine which tenant the application is associated with.
Note that tenants have different user email spaces. That is to say that if I have an account with tenant A and an account with tenant B, they might have different passwords and they will certainly have different user attributes (last login, for example). That may be ok, but just wanted to make you aware. You may want to read the tenants core concepts docs if you haven't already.
-
If you have mor than one tenant defined (as you have) then tenant selection dropdown appears in the application creation view. Create chosen application in the second tenant and discard it in the first one.
-
@mgetka jinx!
-
After carefully comparing the passwordless login that worked with the passwordless that didn't work, I can see that the TenantId on the one that didn't work is incorrect. For some reason FA is trying to use the same tenant ID in both cases. They should be two different tenant IDs. BTW, I am using a different tenant for the registration than for the login. Perhaps this is why when the user tries to login, the wrong tenantID is chosen?
So I guess I will need to :Making an API request using a Tenant Id. I am using Codeigniter so I tried using this $this->output->set_header('X-FusionAuth-TenantId: 8ea1c784-866b-4755-b97b-b4fda2ad19e4'); right before my call to start PasswordlessLogin()
The result I am getting is :
FusionAuth\ClientResponse Object
(
[errorResponse] =>
[exception] =>
[method] => POST
[request] => {"applicationId":"2cf00c29-ac46-49bf-8cd4-32538ddb00d8","loginId":"richardbernstein217@gmail.com","state":{"redirect_uri":"http://substantiator-survey.ngrok.io/index.php/Configure/report_generator_amazing","client_id":"2cf00c29-ac46-49bf-8cd4-32538ddb00d8","response_type":"code","scope":"openid","state":"richardbernstein217@gmail.com"}}
[successResponse] =>
[status] => 404
)Obviously not optimum. But I see I can set an API key:
Using an API key.You may optionally create an API key that is scoped to a particular tenant. To create an API key navigate to Settings API Keys.
Similar to the example screenshot above where we created a new API key, in this example we have selected the Pied Piper tenant for this API key. Only Users, Groups and Applications belonging to the Pied Piper tenant will be visible to this API.
Create a Tenant API Key
HTTP Authorization Header example
The following example demonstrates an API request to an API endpoint requiring tenantId, using the tenant-scoped API key.curl -X POST
-H 'Authorization: oa06-d9uxCHTorBOkVdh_QzsX_iEEYARGv8udnMMLJ8'
-H 'Content-Type: application/json'
-d '{"group": {"name": "Admin"}}'
"http://localhost:9011/api/group"Setting this up requires me to choose an endpoint with Get, put, patch, post, delete. I have no idea how to get my tenant id, 8ea1c784-866b-4755-b97b-b4fda2ad19e4, to work with my call to startPasswordlessLogin. Is there an example anywhere?
-
Some posts ago you have mentioned that both of your apps reside in the same tenant. Moving one of them into another tenant was mentioned but I suppose you have abandoned the idea in the meantime. So, if they are both in same tenant, why would you expect FA to use different tenant ID for each app?
BTW,
$this->output->set_header
sets the header for a response sent to the web browser - data defined this way will never reach FA. -
No you are correct, they are in different tenants. That is why I need to set the "header info" as per the docs.
The docs say that if you have more than one tenant, which I do, that you will need to specify the tenant via the "header". There is even an example: HTTP Authorization Header example
curl -X POST
-H 'Authorization: oa06-d9uxCHTorBOkVdh_QzsX_iEEYARGv8udnMMLJ8'
-H 'Content-Type: application/json'
-d '{"group": {"name": "Admin"}}'
"http://localhost:9011/api/group"But that example makes no sense to someone using the php client.
Please tell me how to tell FA the tenant to use in the context of a php program?
-
Referring to the PHP client source code, the tenant id can be set for the client using
withTenantId
method. Something like this should work:$client->withTenantId(...)->passwordlessLogin(...);
Be aware that
withTenantId
stores the id in the client internal state, and the stored id will be used for all subsequent requests. It may be something that suits you or not - refer to the source code and check how this effect will affect your application.