Using the backdoor creates two tokens
tarzan opened this issue · 4 comments
I am using guardian
in tandem with guardian_db
to persist the JWT tokens in the database. Upon writing the acceptance tests using Hound, I ran into the following issue:
- I followed the instructions in the README and created a
hound_login()
function with
{:ok, token, _claims} = MyApp.Guardian.encode_and_sign(resource)
navigate_to("/?token=#{token}")
- I followed the instruction for
guardian_db
, by implementing (among others) the following hook:
def after_encode_and_sign(resource, claims, token, _options) do
with {:ok, _} <- Guardian.DB.after_encode_and_sign(resource, claims["typ"], claims, token) do
{:ok, token}
end
end
- I wrote an acceptance test that monitors the token is persisted and removed from the database.
- I observed that tokens are persisted in the database twice upon each login.
This has to do with the example implementation that guides the user to first manually encode and sign a token, while the Backdoor Plug picks up on this token, extracts the token and then calls the sign_in
of the Guardian Plug, which itself encodes and signs the token again. This seems unnecessarily complex to me, isn't it possible to shortcut this somehow?
Sorry for the delays @tarzan, I've been out of the country and dealing with a family emergency. One of the @ueberauth/developers will help you soon!
@tarzan what about having a App.Test.Guardian
module under your test/support
files that it doesn't use Guardian.DB
.
To be honest, JWT + Guardian.DB is over killing for testing, you could avoid any database interaction from Guardian if you follow this approach.
@tarzan The example assumes MyApp.Guardian.encode_and_sign/1
is free from side effects. If we extend that function to skip callbacks, we can avoid Guardian.DB issues.
MyApp.Guardian.encode_and_sign(resource, claims, skip_callback: true)
Also, my pull request #4 lets you workaround by passing claims directly instead of tokens. That should avoid double tokens too.
Eventually, we decided to write our own plug for sidestepping authentication in acceptance tests. I put it in a gist right here: https://gist.github.com/tarzan/9d2aad9bb0191587ae4a31e1ded0beb7
This just serialises a user to a JWT token and can be called by implementing a login helper in ExUnit case template:
def login(%{id: user_id}) do
navigate_to("/?user_id=#{user_id}")
end