I recognize that this issue isn't purely a Warden issue -- there are Rails and Devise interactions. That said, this was hideously difficult to track down and I think Warden is best positioned to help users. I also have a fix in mind but wanted to discuss first.
Repro
Essentially, Rails ActionCable requests can exhibit exactly the same problem you guys ran into with #45 . My repro case looks like this:
- Write Capybara / Selenium test that loads a React app with a web browser
login_as create(:user), scope: :user
- Unfortunately, an ActionCable connection triggers a call to
/cable. This could be caused by anything from logging in in the middle of a test, system load, test pollution, phase of the moon, etc.
- My ActionCable setup looks at
env['warden'].user, consuming the one-time data generated by login_as
- The next line of my test does something basic like
visit '/my_profile and is, maddeningly, not logged in.
Pseudocode
So just to be clear, the test looks like this:
login_as create(:user), scope: :user
visit '/my_profile'
But because I'm using a headless browser to run a react app, sometimes an ActionCable request hits the db before the request for /my_profile. This is hideously difficult to debug because I doubt many users have any idea how login_as works under the hood. Especially because of the way ActionCable works and acquires sessions, it tends to be very intermittent. Even with the same db seed, I'd see 1-2 tests fail every 3-4 runs on a full suite.
Fixes
- We can just accept that some users are gonna get screwed by this and hope that they eventually figure out that they need to do what I did, which is just to call:
Warden::Test::WardenHelpers.asset_paths=%r(/(assets/|cable)}
in their test setup. We can add something big and angry to the docs.
-
We could just adjust the default asset_paths to match /cable. It's tricky because rails doesn't stop you from mounting ActionCable on another path, but it would probably save most users from running into this issue. There's also precedent for it.
-
We could be smarter about how Warden behaves. Specifically, we could try to figure out when we're inside ActionCable and prevent ourselves from consuming the on_next_request trigger. I don't know how this would be done and it might risk coupling Warden and Rails. If there's a clean way to do this, that seems like it would be best -- the fundamental problem is that on_next_request is silently failing to do its real job, which is applying the cookie -- but I don't know how we would go about it.
Conclusion
Anyways, let me know what you think. Happy to help you repro it or to try implementing one of the fixes.
I recognize that this issue isn't purely a Warden issue -- there are Rails and Devise interactions. That said, this was hideously difficult to track down and I think Warden is best positioned to help users. I also have a fix in mind but wanted to discuss first.
Repro
Essentially, Rails ActionCable requests can exhibit exactly the same problem you guys ran into with #45 . My repro case looks like this:
login_as create(:user), scope: :user/cable. This could be caused by anything from logging in in the middle of a test, system load, test pollution, phase of the moon, etc.env['warden'].user, consuming the one-time data generated bylogin_asvisit '/my_profileand is, maddeningly, not logged in.Pseudocode
So just to be clear, the test looks like this:
But because I'm using a headless browser to run a react app, sometimes an ActionCable request hits the db before the request for
/my_profile. This is hideously difficult to debug because I doubt many users have any idea howlogin_asworks under the hood. Especially because of the wayActionCableworks and acquires sessions, it tends to be very intermittent. Even with the same db seed, I'd see 1-2 tests fail every 3-4 runs on a full suite.Fixes
Warden::Test::WardenHelpers.asset_paths=%r(/(assets/|cable)}in their test setup. We can add something big and angry to the docs.
We could just adjust the default
asset_pathsto match/cable. It's tricky because rails doesn't stop you from mounting ActionCable on another path, but it would probably save most users from running into this issue. There's also precedent for it.We could be smarter about how
Wardenbehaves. Specifically, we could try to figure out when we're inside ActionCable and prevent ourselves from consuming theon_next_requesttrigger. I don't know how this would be done and it might risk coupling Warden and Rails. If there's a clean way to do this, that seems like it would be best -- the fundamental problem is thaton_next_requestis silently failing to do its real job, which is applying the cookie -- but I don't know how we would go about it.Conclusion
Anyways, let me know what you think. Happy to help you repro it or to try implementing one of the fixes.