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

Using auth option in visit method sets authorization headers in all subrequests #4267

Closed
voslartomas opened this issue May 21, 2019 · 11 comments

Comments

2 participants
@voslartomas
Copy link

commented May 21, 2019

Current behavior:

We have overridden Visit method and adding there auth option (because app we are testing is behind basic http auth). But these headers are sent NOT ONLY to page which is defined in visit method, but also to all sub requests, like for example images and js, which are loaded on page. Is this normal behaviour? Because we have problems with CDN, which is just refusing requests with such header.

Desired behavior:

I would expect authorization header is sent only to defined visit page, not to all requests on page.

Steps to reproduce: (app code and test code)

It seems this is done inside cypress proxy, because if you take a look inside browser there is no header in requests, but if you see logs on server, there is actually Authorization header.

Versions

Cypress 3.3.0

@flotwig

This comment has been minimized.

Copy link
Member

commented May 23, 2019

cy.visit only controls options for for the original request. Support for adding a header to ALL requests will be added with #687.

@voslartomas

This comment has been minimized.

Copy link
Author

commented May 23, 2019

@flotwig exactly, so it should not propagate headers to requests in visited page right? But it does at the moment, which seems as a bug to me.

@flotwig

This comment has been minimized.

Copy link
Member

commented May 23, 2019

Oh, I misunderstood at first. Yes, this is how the auth option works. From the docs for cy.visit:

...provide the username and password in the auth object. Then all subsequent requests matching the origin you’re testing will have these attached at the network level.

If you only want to apply Authorization headers for the initial cy.visit, you could supply them as headers, instead of on the auth object:

let username = "username"
let password = "password"
cy.visit({
	url: '/needs-auth',
	headers: {
		'Authorization': `basic ${btoa(`${username}:${password}`)}`
	}
})

The headers above should only apply to the initial request.

@voslartomas

This comment has been minimized.

Copy link
Author

commented May 23, 2019

I see, so headers. Thank you!

@voslartomas voslartomas reopened this May 23, 2019

@voslartomas

This comment has been minimized.

Copy link
Author

commented May 23, 2019

@flotwig Ehm, actually that is not solution for us. Because we need to have this header to download js and css files. So going again with auth, as you said it should send this header only to subsequent requests MATCHING the origin. Does this mean, when visiting beta.something.com it should send this header only to beta.something.com. Not to cdn.something.com, right??

@flotwig

This comment has been minimized.

Copy link
Member

commented May 23, 2019

It matches the domain using urlMatchesOriginPolicyProps in cors.js. It looks like this takes the top-level domain suffix, second-level domain (as determined by the public suffix list), and port to match on.

So if you do a cy.visit('http://beta.something.com', { auth: { /*...*/ } } ), it will send those auth headers with every subsequent request to something.com and *.something.com.

Because we need to have this header to download js and css files.

How does this normally work in a browser for your application? Do you use a browser extension to supply Authorization?

@voslartomas

This comment has been minimized.

Copy link
Author

commented May 23, 2019

Well I don't think this is correct behaviour, right? Normally how browsers implement this, is Authorization header is sent only to beta.something.com, not to cdn.beta.something.com etc. So our app is working normally in browsers, only problem we have is cypress proxy now.

@flotwig

This comment has been minimized.

Copy link
Member

commented May 23, 2019

Hmm, I think you are right, this may be a bug. RFC 7235 section 2.2 (HTTP authentication) says:

   A protection space is defined by the canonical root URI (the scheme
   and authority components of the effective request URI;
   .....
   The protection space determines the domain over which credentials can
   be automatically applied.  If a prior request has been authorized,
   the user agent MAY reuse the same credentials for all other requests
   within that protection space for a period of time determined by the
   authentication scheme, parameters, and/or user preferences (such as a
   configurable inactivity timeout).  Unless specifically allowed by the
   authentication scheme, a single protection space cannot extend
   outside the scope of its server.

The RFC and Chrome both interpret "protection space" to mean a unique scheme + FQDN + port combination. Cypress appears to be treating everything under the same SLD + TLD + port as a single "protection space", which is incorrect. This will need to be fixed, thanks for your help in tracking this down.

@voslartomas

This comment has been minimized.

Copy link
Author

commented May 23, 2019

Sure, no problem, thanks for noticing me :)

@cypress-bot

This comment has been minimized.

Copy link

commented Jun 19, 2019

The code for this is done in cypress-io/cypress#4338, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

@cypress-bot

This comment has been minimized.

Copy link

commented Jun 27, 2019

Released in 3.3.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.