I'm trying to test my website where users authenticate via session cookie without having to automate the whole manual logging process using the Chrome debugger solution suggested here https://github.com/GoogleChrome/lighthouse/blob/master/docs/readme.md#testing-on-a-site-with-authentication, so I'm trying to directly set the cookies using the --extra-headers flag.
lighthouse https://authenticated-website.com --chrome-flags="--headless" --extra-headers=./headers.jsonThe content of headers.json is as follows:
{
"Cookie": "session_id=whatever-session-id"
}
When lighthouse accesses the website, there's a call to an authentication API that returns a set-cookie header with a csrf token. From that request onwards, the user is unauthenticated. All of the requests are sending the cookie with the csrf token (returned via set-cookie) but are completely disregarding the headers I set in the beginning, overriding the original "Cookie" header instead of appending the value. I enabled extra logging and see on the network responses that the headers received are not the expected ones:
{
"method": "Network.responseReceived",
"params": {
"requestId": "1000019523.17",
"loaderId": "5D025634B8EEDC4CF37CCC23430142BB",
"timestamp": 52153.046111,
"type": "Fetch",
"response": {
"url": "https://authenticated-website.com/whatever.json",
"status": 200,
"statusText": "",
"headers": {
"date": "Tue, 09 Oct 2018 16:44:06 GMT",
"content-encoding": "gzip",
"x-content-type-options": "nosniff",
"x-permitted-cross-domain-policies": "none",
"status": "200",
"vary": "Accept-Encoding",
"content-length": "219",
"x-xss-protection": "1; mode=block",
"pragma": "no-cache",
"last-modified": "Tue, 09 Oct 2018 15:52:20 GMT",
"server": "none",
"x-frame-options": "SAMEORIGIN",
"x-download-options": "noopen",
"strict-transport-security": "max-age=31536000; includeSubdomains; preload\nmax-age=31536000; includeSubdomains;",
"content-type": "application/json",
"region": "EU",
"cache-control": "max-age=0, no-cache, no-store, must-revalidate",
"accept-ranges": "bytes",
"x-robots-tag": "none",
"expires": "Wed, 11 Jan 1984 05:00:00 GMT"
},
"mimeType": "application/json",
"requestHeaders": {
":path": "/whatever.json",
"accept-encoding": "gzip, deflate",
"user-agent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MRA58N) AppleWebKit/537.36(KHTML, like Gecko) Chrome/71.0.3559.0 Mobile Safari/537.36",
"accept": "*/*",
"referer": "https://authenticated-website.com",
":authority": "authenticated-website.com",
"cookie": "csrf_token=whatever-csrf-token",
":scheme": "https",
":method": "GET"
},
"connectionReused": true,
"connectionId": 9
....
Cookie returned in set-cookie should be appended, making the headers from that point onwards look like this:
{
"Cookie": "session_id=whatever-session-id; csrf_token=whatever-session-token"
}
I'm running Chrome 69.0.3497.100.
Related issues
https://github.com/GoogleChrome/lighthouse/issues/1418
Thanks for filing @robespmun!
Just so I get this straight...
--extra-headers to override the session_id but you still want to let the csrf_token go through--extra-headers is clobbering the csrf_token and you're just getting the session_id (or is it vice-versa)?Is that an accurate description of what's happening?
The whole process is:
--extra-headers to set a valid session_idAh, I see. Yeah that's some peculiar behavior 😕 I wouldn't expect setExtraHTTPHeaders to ever be able to merge the values though so just one of them was going to be able to win.
My only suggestion for an immediate workaround would be to use puppeteer to set a real cookie as soon as the page loads or include a CSRF token with the headers.json.
We'll have to decide what the correct behavior really should be. My guess is that from the Chrome-perspective this is WAI and Chrome should not be automatically setting this cookie on all domains just because the Cookie header has been overridden.
I think this issue breaks the possibility of using lighthouse on any enterprise level project on CLI mode (i.e in CI) and I add +1 for the criticality of this issue. I came across exactly the same behavior: any Set-Cookie response from backend overwrites the Cookie header from extra-headers.
1) lighthouse http://localhost/ --extra-headers "{\"Cookie\":\"test=true\"}"
2) Request header: Cookie: test=true
Response header: Set-Cookie: locale=en;
3) All subsequent requests headers:
Actual request headers : Cookie: locale=en
Excpeted request headers: Cookie: test=true; locale=en
So I decided to play with the code https://github.com/RynatSibahatau/lighthouse/commit/5a8b8ceb9fbd1ac8834d33116958ef24b2dcf6f7 and have introduced a new CLI parameter:
lighthouse http://localhost/ --extra-cookies "[{\"name\":\"test\", \"value\": \"true\", \"url\": \"http://localhost\"}]"
This command works as expected behaviour.
If you support me to have this parameter in the lighthouse's master branch, I can do extra polishing/add extra tests and create a PR.
Thank you!
Thanks @RynatSibahatau that looks like a great starting point for a PR already! Personally, I'm fairly convinced this is a worthwhile use case to support in aid of #1418 without resorting to #3837, especially in CI cases. I'd be happy to assist with your feature PR and make the case to the rest of the team.
The only issues I think I currently see is how this behavior is intended to interact with other cookie settings and the specific JSON format expected, but we can discuss those details in the PR if you wish to proceed :)
Is there anything I can do to help push this along? The pull request has been open for 2 months and is currently “waiting4commiter”. I could really do with this feature.
Hi, in my test case, I fond the main reason that why rest request will losing the cookie in --extra-headers is not the evil of set cookies.
The main reason is when chrome exists real cookie, the cookie in --extra-headers will be ignored.
And the network panel of chrome-devtools can't display real cookie sent to server.
In my test case:
real cookie: WM_NI=xxx;WM_NIKE=xxx;WM_TID=xxx;
extra-header:
{
"Cookie": "MUSIC_U=xxxx"
}
we can use lighthouse --port to use an existing chrome instance, and set real cookie, then, we will get the test result:
Summary, set cookies -> real cookie -> cookie in extra-headers be ignored, and chrome' devtools may have display bug.
Thanks very much for the additional debug info @kkdev163 that's super helpful! This should be addressed by #9170 if we can get it across the finish line.
We'll plan to solve this use case as part of Fraggle Rock work #11313 but we're not going to solve this specific CLI flag issue.
Most helpful comment
I think this issue breaks the possibility of using lighthouse on any enterprise level project on CLI mode (i.e in CI) and I add +1 for the criticality of this issue. I came across exactly the same behavior: any Set-Cookie response from backend overwrites the Cookie header from extra-headers.
1)
lighthouse http://localhost/ --extra-headers "{\"Cookie\":\"test=true\"}"2) Request header: Cookie: test=true
Response header: Set-Cookie: locale=en;
3) All subsequent requests headers:
Actual request headers : Cookie: locale=en
Excpeted request headers: Cookie: test=true; locale=en
So I decided to play with the code https://github.com/RynatSibahatau/lighthouse/commit/5a8b8ceb9fbd1ac8834d33116958ef24b2dcf6f7 and have introduced a new CLI parameter:
This command works as expected behaviour.
If you support me to have this parameter in the lighthouse's master branch, I can do extra polishing/add extra tests and create a PR.
Thank you!