Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Auth #9569

Closed
connorjclark opened this issue Aug 16, 2019 · 7 comments
Closed

Question: Auth #9569

connorjclark opened this issue Aug 16, 2019 · 7 comments

Comments

@connorjclark
Copy link
Collaborator

(related: #1418. Separate issue b/c this is just me asking if my approach makes sense, and this got a bit too long-form for our internal chat)

So I'm starting to write docs for LH on authenticated pages. I know little about auth stuff. I see some stuff on JWT. And cookies. and then there's Basic auth. and feeling a bit lost, so let my run this by y'all.

I want to make a local server that does a few different methods of auth to test stuff out. Here's a simple basic auth server in python: https://gist.github.com/dragermrb/108158f5a284b5fba806 . I'll probably make a cookie / token based one too.

  1. Does this sound right - am I missing anything?
  2. An alternative to setting headers / cookies via LH CLI flags is to use a custom Chrome profile, and set it up however you want, then instruct LH to use that. I don't know if that actually covers anything more than the header flags would - does it?
@patrickhulce
Copy link
Collaborator

patrickhulce commented Aug 17, 2019

I don't know if that actually covers anything more than the header flags would - does it?

I'll throw a few more out there. Some don't wish to construct the header on their own but want to ensure the app is properly picking it up from wherever they're storing it.

localStorage/indexedDB/sessionStorage are some common ways of storing the token and so doing some pre-work (like controlling with puppeteer or manually creating a chrome profile) is a common way to put it there. sessionStorage is the biggest gap we have right now as it's just not really possible to have a token used from sessionStorage and have LH pick it up in a clean way, the rest you can just use --disable-storage-reset

Also worth noting that I've seen several systems in the past where they use a bespoke header for the token but for the most part our --extra-headers approach should still cover it.

The only major missing case I see is when they use a query param or JSON property in the payload for the token. In which case we have to support letting them drop it into their particular storage of choice.

@connorjclark
Copy link
Collaborator Author

Thanks @patrickhulce!

localStorage/indexedDB/sessionStorage are some common ways of storing the token and so doing some pre-work (like controlling with puppeteer or manually creating a chrome profile) is a common way to put it there. sessionStorage is the biggest gap we have right now as it's just not really possible to have a token used from sessionStorage and have LH pick it up in a clean way

We could introduce --session-storage="{...}" and --local-storage="{...}" w/ DOMStorage.setDOMStorageItem - this will let users set local/sessionStorage from the CLI.

There's no protocol methods for writing to IndexDB, so that will continue to require a chrome profile / puppeteer setup. We could do something bespoke using Runtime.evaluate.

The only major missing case I see is when they use a query param or JSON property in the payload for the token. In which case we have to support letting them drop it into their particular storage of choice.

Could you elaborate on this?

@patrickhulce
Copy link
Collaborator

patrickhulce commented Aug 19, 2019

We could introduce --session-storage="{...}" and --local-storage="{...}" w/ DOMStorage.setDOMStorageItem

I like this idea! A convenience for pre-populating is nice without having to spin up puppeteer 👍Though I might want to try to avoid flag bloat with some --storage.X collection of flags for managing all this junk.

Could you elaborate on this?

Yeah I was just saying the missing case that isn't covered by --extra-headers is when the token that is stored in localstorage/indexeddb/sessionstorage is appended to the URL as a query param or JSON payload since there's no way to way in raw LH to mutate request body/URL. If we address all the places that a token could be stored as you've suggested then I think we would be good.

@paulirish
Copy link
Member

paulirish commented Aug 19, 2019

It's true that user account/login state can be defined in lots of different ways. localStorage, cookies, indexedDB, etc.

Stepping back, I don't see users actually asking for this. In fact, looking at #1418, it's us who are suggesting setting cookies/headers as a means to do this.

Meanwhile, when an example of using puppeteer to login was posted, it quickly got the most 👍 reactions in the thread.

Similarly, the WPT scripting language is mostly used to fill in login forms.

My suspicion is that folks who currently have integration tests on their login-based webapp are logging into them with forms rather than prefilling *storage state or setting request headers. I also think this is far more user-friendly.

IMO the ask here is to document using pptr to login and handing off to lighthouse. This comment laid the groundwork, but it could afford to be generalized.

We should also mention the two backup solutions of.. A) extra-headers and B) chrome profile reuse.

@connorjclark
Copy link
Collaborator Author

Thanks @paulirish. I do plan on making the puppeteer use-case the focal point of the documentation I'll write. Wanted to also cover all the other cases.

I've started to uncover some possible gaps in LH's ability to do the alternatives, and think it's important to improve these shortcomings aswell as write the docs for it. These are blockers I've identified for providing a comprehensive guide for auth:

  1. land core: added capability to pass cookies as CLI parameter #9170 for full coverage on cookie based auth
  2. using a custom profile (via CLI) is currently not supported b/c of the way we use chrome-launcher: Using specific Chrome profile #8957
  3. populate various storages, as @patrickhulce suggests.

I'll switch focus to just writing the pupeteer docs now - even 2) can be circumvented as long as you use puppeteer to launch.

Meanwhile, when an example of using puppeteer to login was posted, it quickly got the most +1 reactions in the thread.

Similarly, the WPT scripting language is mostly used to fill in login forms.

I wonder, if pupeteer is needed to simply fill a form, and WPT even has a scripting feature to do this ... maybe we should just do that? Instead of requiring puppeteer be thrown into the mix?

@patrickhulce
Copy link
Collaborator

Oh yes to be clear, massive +1 to supporting an actual e2e testing flow for using the UI as intended to login. Just wanted to make sure we were aware of the various auth mechanisms and can support them or at least address the required workarounds in this documentation. (for example sessionstorage is still impossibleish with a puppeteer prestep because we open the new tab, etc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants