I am implementing signup and login for a SaaS application where every user is linked to an organization. Let’s say my application has the URL myapp.com, and every organization has a unique subdomain under my website e.g. myclient1.myapp.com
I have to derive organization ID from the unique subdomain myclient1 and assign it to organization_id field of user table in the database for every signup. For login also, I need to derive the organization_id and find the user by organization_id and the email.
How can I implement this correctly using AshAuthentication? I believe I need to use a custom strategy and make the database call there to fetch organization by unique subdomain and set the organization_id in changeset?
And how do I access the hostname in change method of the custom strategy? With Phoenix, I get this with Plug.Conn by using conn.host. But with Ash custom strategy, I inspected all the available variables - changeset, options and context, it doesn’t seem to be there.
1 Like
Generally this would be done by using multitenancy
, and you’d set the tenant
in a plug. For example,
In your user resource
multitenancy do
strategy :attribute
attribute :organization_id
global? true # allows working with all orgs without setting a tenant
end
Then, in a plug ahead of the authentication logic, use set_tenant/2
from here Ash.PlugHelpers — ash v2.18.1 to set the tenant to the organization.id
that you looked up from the plug.
AshAuthentication honors the tenant when interacting with your user resource. When a tenant is set while using the attribute strategy, the attribute is written to on changes and used in filters when accessing the data.
2 Likes
Thanks for the quick reply. I will give it a try.
A follow up question. Before the signup step, I am also verifying the email by sending a verification code to the email the verification code is stored in user_verifications table in the database.
The signup call happens after the user enters the password. At this stage, I need to make a DB call to check if the email is verified. What is the best way to check this? Do I need to implement a custom strategy/addon and make the DB call and throw an error if the email is not verified?
Here is what my signup flow looks like:
Are you using the built in confirmation tooling in ash_authentication
? Regardless, the best way to handle this typically is to add a plug after authentication that checks if the user has been confirmed, and if not redirect to the “please verify your email or resend” page.
3 Likes
No, I was not using the built in confirmation tooling. I was looking at the docs for that here. It seems that confirmation tooling is used only for updates, but I’m creating a new record in the signup action. Is it possible to use confirmation tooling while creating a record?
@jimsynz can correct me if I’m wrong, but this will work for creation as well as updates. You can then add a plug to check if confirmed_at
is not set, and if not, redirect to a page telling them to check their email.