Forbidden magic link
Can't get magic link to work all of a sudden. I receive the magic link in
dev/mailbox
but when I click it I'm taken to a page that has a "sign in" button, and once I click that, I get:
57 Replies
is the token expired?
I don't beleieve so. It is set to expire after 10 mins and I am clicking it immediately.
What does your link format look like? Perhaps using the wrong parameter name etc? Newer versions of Ash authentication have you doing it with a path param not a query param etc.
My link looks like this:

A bit of extra disclosure.
I added a
set_tenant
plug that looks like:
Not sure if this could be causing an issueIs your token resource multitenant?
To be honest, I am not sure how to check that. I just finished reading the Ash Framework book a few days ago. My Token module is too big to paste here but running a search on it for the word
multi
returns no results:
Hmm...so it shouldn't be then. In your first message you said "all of a sudden" does this mean this was working and then stopped?
Yes it worked a couple days ago.. I was happy and went to sleep. This is the story: at first I could not get it to work after I added multi tenancy following this tutorial: https://alembic.com.au/blog/multitenancy-in-ash-framework but I got help in the Ash slack and added the plug I mentioned. It worked at that moment.
Then today I used:
mix ash_phoenix.gen.live --domain MyApp.Facilities --resource MyApp.Facilities.RegionalOffice
And you know how it asks you something about usiong :current_user
? I said yes.
After that I could no longer log in via magic links. Though this observation of mine may be completely unrelated. I am just trying to provide more context.Alembic
š Mastering Multitenancy in Ash Framework
Learn how to keep customer data securely separated in your Elixir apps - without the headache. All you need to know from basic setup to advanced ID management.
š¤ hmm...that shouldn't modify the magic link process
We can potentially improve that error message to provide more context
but other than that it might be worth rolling back your changes/checking out an older commit to see exactly which changes caused the issue
Thank you, I will try that
No dice.. I am not sure what the problem is š¦ is there a place where I can put some logging in order to find out what the issue is?
I'll look and see if we're swallowing a more descriptive error somewhere
but you can also add some logic to the
sign_in_with_magic_link
action
which I believe should be a create action in the standard setupKk thank you so much
so you can do something like:
in the log
which should print out a bunch of details about the action
And/or you can do your own thing there:
for example
This seems like a hint?
My guess is that by adding the following
set_tenant
plug I messed something up:
It felt like a hack from the beginning but cant find documentation as to how to set the user to the appropriate organization when they attempt to login:
Right, so this depends a lot on your setup
When you say "set the user to the appropriate organization when they attempt to login", what do you mean?
I've pushed something up to
main
of ash_authentication
that should provide more detailed error information as part of the magic link flowI mean, lets say
johny@test.com
is a member of organization_id 1
.
And mickey@hey.com
is a member of organization_id 2
When johny comes to localhost:4000/sign_in
he does not need to tell us his organization, he jsut types in his email and we already know, so to speak, that he belongs to organization 1how do you enforce that?
What if organization 1 & organization 2 have users w/ the same email?
Ah I didn't know that was possible
Well, it depends on how you've set up multitenancy
Each resource is in control of its own multitenant definition
So how is the multitenancy on your user resource configured?
I frankly don't fully understand how multitenancy works in Ash. In previous projects (Phoenix only) I would have to add an org_id column to each and every one of my "objects" but I get the sense that this is not the case with Ash
Its effectively the same for Ash when you use the attribute multitenancy approach
The only difference is that setting the tenant does the filtering etc.
The main thing is that with that setup as you have it now, you have essentially a chicken and an egg problem
You can't ever fetch a user because it requires a tenant to be given
but you won't know the tenant until you fetch the user
In many cases, what people do is use subdomains for tenants for example
so that users visit
org1.myapp.com
and org2.myapp.com
for example
then you fetch the org first thing and you can set a tenant and you're off to the racesthat makes sense, and I am happy to use subdomains, but how would this work in dev? would I do tenant.localhost:4000?
Locally its a bit complex, you have to modify your
/etc/hosts
(are you on a mac/linux?)Linux. I am on Ubuntu 24.04
For local testing you have to tell your machine about those subdomains
put something like that in your
/etc/hosts
and then you can visit foo.localhost
and bar.localhost
then, early on in your pipeline, you fetch the corresponding organization (this is typically done by having orgs choose a unique subdomain when they are created), and then use Ash.PlugHelpers.set_tenant
.
Now, with all that said, you have a different chicken and egg problem when it comes to registration š. This often requires building custom sign in views because we don't provide this one out of the box. Because now you have a user who can't be created until an organization exists for them to be a part of.
So you have to modify your register action to have inputs that can create an organization etc.and that makes sense
Do you think my set_tenant plug is too late here?
Your life will in general be much simpler instead of you choose to make users not multitenant at all, but I don't know if thats on the table for you.
yes, likely so
should be above
load_from_session
If you're familiar with how github models it for example, you can have one global users table, that has a many_to_many
to the organizations they have access to. After a user signs in, if there is only one organization they are a part of, you can redirect to that_org.your_app.com
. If there are many, you can redirect them to a page to select the organization they'd like to view, for example.Interstingly, I dont actually see a
sign-in
route in my router.ex
but somehow I am able to visit localhost:4000/sign-in
Yeah, that is added by the ash_authentication code
Like this stuff:
ah, cool!
Should I just update all my deps and see if the error is more descriptive?
You'll have to point to main
{:ash_authentication, github: "team-alembic/ash_authentication", override: true}
since its not released yetkk thanks so much
I will do so now
LMK how it goes š
Done. Not sure if the extra logging is contained here?
https://pastebin.com/k7FzpPPq
Pastebin
[warning] Authentication failed: Bread Crumbs: > Error returned fr...
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
And I modified my pipeline to look like this:
Hmm...
sorry its not extra logging but that message should just have more stuff in it š¤
What I did is modified my
mix.exs
and then mix deps.update --all
hmmmm
the stacktrace doesn't look quite right
š¤¦āāļø
sorry
mix deps.update ash_authentication
it helps if I push the changes...
Should I still use the one you provided or the original one?
by the way nothing to be sorry about Ash is absolutely incredible, I can't even believe it exists
Yeah still use the one I provided š
Thank you. This is what I see:
https://pastebin.com/VzQQwpFy
Pastebin
[debug] HANDLE EVENT "submit" in AshAuthentication.Phoenix.MagicSig...
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
š¤ hmmmmmm
Okay
I think your tokens need to be tenanted just like your users
can you set them up the same way?
add this to the Token module?
yep š
and
mix ash.codegen <name>
kk doing it now
while I do this, can I ask you if you think this is something I have caused? I would like to stick to the "official" Ash way of doing things as much as possible
Honestly I think there is likely just something simple that isn't set up as expected, either something misconfigured or something not documented properly on our end etc.
There are plenty of people using Ash Authentication w/ multitenant setups
so its definitely doable š
kk awesome! I have added these two under the Token resource:
And applied the migrations in question
Did you issue a new token or are you using one that was already sent?
Also, what does your browser pipeline look like now?
This is my pipeline:
I went to
localhost:4000/sign-in
and generated a new token that way. Then received the email in dev/mailbox
, clicked the magic link and then clicked "sign in" on the page that I was taken toHum
This may in fact be a bug
try updating to latest main again
So maybe I'm wrong and people arne't using magic link w/ tenanted users
Or perhaps folks haven't upgraded to whichever version introduced this bug
its good and bad, the builtin protections prevent from making invalid queries, so its not a security issue, but of course needs fixing
it worked!
š„³
You may also not need the multitenant token setup
But hard to say š
how do I roll that back? hah
two ways
you can roll "forward"
and just remove that stuff, and regen migrations
or you can delete the snapshots you added, and the migrations, and reset your local database
The
--dev
flag can help in the future, if you use that then all the migrations are marked as _dev
migrations and will be rolled back and deleted when you do mix ash.codegen
without the --dev
flagah interesting, thank you!
do you know what the issue was? I hope I was at least a little help :p
Absolutely!
You helped find a bug that anyone trying what you tried would have had š
Essentially just not passing an option down when verifying the token š
Will release the fix for it tomorrow or the day after.