cypress icon indicating copy to clipboard operation
cypress copied to clipboard

Cypress + AWS Cognito Hosted UI = /error ?

Open DimiTech opened this issue 3 years ago • 15 comments

Current behavior

We are testing a Web Application, and for some reason the AWS Cognito Sign In (using the Cognito Hosted UI) doesn't work -> Cognito just redirects to /error instead of the given redirect_uri. (see screenshots)

This Sign In flow works flawlessly when directly using the application.

Screen Shot 2022-03-25 at 4 26 22 PM Screen Shot 2022-03-25 at 4 25 00 PM Screen Shot 2022-03-25 at 8 21 13 PM

The most suspicious thing here is the Insecure HTTPS caused by cypress using its CypressProxyCA when running tests - I think there might be something wrong there?

We have tried adding the Amazon/CloudFront certificates but that doesn't work because we need the corresponding Private Keys (which we don't have of course).

Tried looking at the Cognito logs but there's nothing useful there either.

Tried playing with other settings/configuration but nothing works.

Is there any solution to this, has anyone used AWS Cognito and Cypress in this way before?

Thanks in advance!

Desired behavior

We expect the Cognito Hosted UI - OAuth2.0 Authorization Code flow to work the same as it does when using the Web Application directly.

Test code to reproduce

.

Cypress Version

9.5.2

Other

No response

DimiTech avatar Mar 25 '22 15:03 DimiTech

@DusanDimitric Were you able to resolve this error with some other workaround?

suresh-raja-nxtgen avatar Jul 10 '22 03:07 suresh-raja-nxtgen

same issue here, any solutions?

convers39 avatar Sep 28 '22 09:09 convers39

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.

github-actions[bot] avatar May 12 '23 17:05 github-actions[bot]

This is happening for me in the latest version of Cypress (12.12.0).

From my testing, I'm not sure this is anything to do with certificates, because if you open the Cognito Hosted UI in the Chrome instance Cypress uses you get the same insecure certificate warning, but the process works.

RandomComm3nt avatar May 24 '23 06:05 RandomComm3nt

Hi @RandomComm3nt. Are you able to get AWS Cognito login to work? We have a guide on how to perform hosted login with Cognito. The insecure certificate is likely a red herring, as the cypress proxy server generates certs in order to wrap your application with top being your test URL.

AtofStryker avatar May 24 '23 13:05 AtofStryker

Unfortunately we have to close this issue due to inactivity. Please comment if there is new information to provide concerning the original issue and we can reopen.

AtofStryker avatar Jun 01 '23 23:06 AtofStryker

Hi, I've only just had a chance to play with this some more.

I've created two tests that seem like they should be identical. The first test correctly authenticates with Cognito and is redirected back to localhost, but the second test gets a Cognito error (screenshot below).

describe("template spec", () => {
  it("passes", () => {
    cy.visit("localhost:3000");
    cy.get("a").click();

    cy.origin("cypress-test.auth.eu-west-2.amazoncognito.com", () => {
      cy.get(`input[name="username"]:visible`).type("test-user");
      cy.get(`input[name="password"]:visible`).type("Cypress1!");
      cy.get(`input[name="signInSubmitButton"]:visible`).click();
    });

    cy.get("a");
  });

  it("fails", () => {
    cy.visit("localhost:3000");
    cy.get("a")
      .invoke("attr", "href")
      .then((href) => {
        cy.visit(href);
      });

    cy.origin("cypress-test.auth.eu-west-2.amazoncognito.com", () => {
      cy.get(`input[name="username"]:visible`).type("test-user");
      cy.get(`input[name="password"]:visible`).type("Cypress1!");
      cy.get(`input[name="signInSubmitButton"]:visible`).click();
    });
    cy.get("a");
  });
});

image

Full source code of this example attached.

cognito-cypress-test.zip

RandomComm3nt avatar Jun 02 '23 11:06 RandomComm3nt

@RandomComm3nt I was able to give this a run and reproduce it. This looks like a bug to me. It doesn't seem to be an issue with cookie jar state or order of the test, but for some reason a cy.visit() on the direct amazon link causes a bad request. What I think might be happening is something in the proxy is modifying that request in a way that makes some of the Set-Cookie headers go missing Screenshot 2023-06-02 at 11 15 51 AM, which is likely why the error req follows, which tells me there is something wrong with this request in the second test case. In the mean time, are you able to leverage the first case in your tests as a work around?

AtofStryker avatar Jun 02 '23 15:06 AtofStryker

I'm wondering why this isn't fixed yet. In my opinion the underlying bug is a major issue that probably holds back many people from using Cypress at all, when you can't login through third-party providers using cookies.

I now made this workaround which seems to work for me:

const COGNITO_HOST = 'my-url.amazoncognito.com'
let xsrfToken: string;
cy.intercept({
  method: 'POST',
  url: '/login*'
}, (req) => {
  req.headers['Cookie'] = `XSRF-TOKEN=${xsrfToken}`;
});
cy.origin(COGNITO_HOST, () => {
  cy.get('input[name="username"]:visible').type('user');
  cy.get('input[name="password"]:visible').type('password');
  cy.getCookie('XSRF-TOKEN').its('value');
}).then((token: string) => xsrfToken = token);
cy.origin(COGNITO_HOST, () => {
  cy.get('form[name="cognitoSignInForm"]:visible').submit();
});

xxluke avatar Aug 24 '23 14:08 xxluke

Reached here while setting-up a new e2e suite for an existing application.

Behavior is the same at Chrome, Firefox and Electron browsers: finishing at /error because form POST misses XSRF tokens

Tried @xxluke 's workaround without luck in this case. Cypress isn't able to access that XSRF-TOKEN cookie so we can't patch the form POST /login request. Some warning messages at consoles on different browsers which may relate:

  • Chrome v124 rejects document.domain usage see document domain setter deprecation:

    The page did not request an origin-keyed agent cluster, but was put in one anyway because the origin 'https://redacted-domain-of.cognito-instance.example' had previously been placed in an origin-keyed agent cluster. Update your headers to uniformly request origin-keying for all pages on the origin.

    document.domain mutation is ignored because the surrounding agent cluster is origin-keyed.

  • Firefox v125 rejects the XSRF-TOKEN:

    Cookie “XSRF-TOKEN” has been rejected because it is in a cross-site context and its “SameSite” is “Lax” or “Strict”.

  • Electron v118 does not give warnings at all

Will still give a try to the "click on link" trickery because application uses server-side redirection, and report back here any findings

lorenzogrv avatar Apr 23 '24 09:04 lorenzogrv

Adapting the "click on link" trickery which explains @RandomComm3nt here the flow can complete succesfully

lorenzogrv avatar Apr 24 '24 08:04 lorenzogrv

Did anyone find a solution? I am facing this error while using the origin. If I use cy.visit(), it works, but the screen reloads every test due to a domain change.

tjoaoguimaraes avatar Aug 12 '24 16:08 tjoaoguimaraes

Did anyone find a solution? I am facing this error while using the origin. If I use cy.visit(), it works, but the screen reloads every test due to a domain change.

@tjoaoguimaraes have you tried setting experimentalModifyObstructiveThirdPartyCode to true?

AtofStryker avatar Aug 12 '24 16:08 AtofStryker

Did anyone find a solution? I am facing this error while using the origin. If I use cy.visit(), it works, but the screen reloads every test due to a domain change.

@tjoaoguimaraes have you tried setting experimentalModifyObstructiveThirdPartyCode to true?

Yes, I did, but it does not work. My problem is that the cognito POST request returns a 400 status code, the same issue OP is facing.

tjoaoguimaraes avatar Aug 12 '24 17:08 tjoaoguimaraes

After more than two weeks of struggling to find a solution, I finally made it.

While inspecting the network requests made by Cypress during test execution, I noticed a warning in a request stating:

“This attempt to set a cookie via a Set-Cookie header was blocked because it had the ‘SameSite=Lax’ attribute but came from a cross-site response which was not the response to a top-level navigation.”

After some Googling, I found this blog post: https://www.tomoliver.net/posts/cypress-samesite-problem

By reproducing the steps provided, everything worked as expected.

Hope it helps!

tjoaoguimaraes avatar Aug 22 '24 19:08 tjoaoguimaraes

I am having the same issue and thanks @tjoaoguimaraes for the solution, it does work, but maybe too much overhead? When would this fixed please? It has been 3 years....

cypress v14.2.0, chrome 134

miaoz2001 avatar Mar 25 '25 07:03 miaoz2001

What worked for me was to change my login command so it actually clicks on a login link to redirect to the SSO URL with the login form, rather than trying to call cy.visit() to visit a page that redirects there automatically.

Not sure if I'm facing exactly the same issue, but I was definitely having a cross-domain login issue with cookies not being set (due to the SameSite issue described here that @tjoaoguimaraes mentioned above).


And I just discovered another workaround: if you don't want to actually load a page and click a login link, and you're able to get the URL that you would use as the href for such a link into your cypress test, you can do this:

cy.window().then((win) => {
    win.location.href = sameUrlAsActualLoginLink
})

// code to submit login form

mbrowne avatar Oct 02 '25 19:10 mbrowne