Logging in with Next Auth to a Keycloak account during testing in Cypress

Trying to create e2e tests with Cypress for my NextJs Application. Currently using Next Auth to log into my keycloak account via OAuth and displaying certain nav bar elements based on keycloak roles. To test this, I set up a test realm with test users. However, encountering an error where the State cookie was missing. message from Next Auth appears after attempting to log in during the test process. The same steps work fine when manually testing in the browser.

Steps when testing manually:

  • Visit the home page
  • Click on login
  • Redirected to keycloak
  • Enter username
  • Enter password
  • Login successful, redirected back to home page

Steps when testing with Cypress:

  • Visit the home page
  • Click on login
  • Redirected to keycloak
  • Enter username
  • Enter password
  • After clicking login, redirected to Next Auth error page
  • Error message: State cookie was missing.
  • Login failed

Any ideas why Cypress is behaving this way?

Your help is greatly appreciated!

EDIT:

Noted that the next-auth.state cookie still exists upon revisiting the page (verified by checking cookies) post login button click, even though Next Auth claims it doesn't. Confusing situation.

EDIT 2:

Cypress seems to have the cookie, but it's not being passed to my web app as the application's request does not contain any cookie information.

Answer №1

To address the issue, I resolved it by adjusting next-auth's cookies to have a SameSite=None attribute. Below is the snippet of code I implemented (using Auth0 in this instance):

function loginViaAuth0Ui(username: string, password: string) {
  cy.intercept("/api/auth/**", (req) =>
      req.on("response", (res) => {
        const setCookies = res.headers["set-cookie"]
        res.headers["set-cookie"] = (
            Array.isArray(setCookies) ? setCookies : [setCookies]
        )
            .filter((x) => x?.startsWith('next-auth'))
            .map((headerContent) => {
                  const replaced = headerContent.replace(
                      /samesite=(lax|strict)/gi,
                      "secure; samesite=none"
                  )
                  // console.log('replaced', headerContent, 'with', replaced)
                  return replaced
                }
            )
      })
  )

  cy.visit('account')
  cy.findByTestId('auth0-button').click()

  cy.origin('https://my-site.uk.auth0.com/', {args: {username, password}}, ({username, password}) => {
    cy.get('input#username').type(username)
    cy.get('input#password').type(password, {log: false})
    cy.contains('button[value=default]', 'Continue').click()
  })


  cy.url().should('include', '/account')
}

Summary

The root cause lies within the cookie settings and is elaborated on in this article: (which inspired my approach). In essence, next-auth's cookies are configured with a SameSite=Lax attribute, leading to Cypress encountering issues due to running within an enclosed context. Chromium consequently blocks the requests as they are not considered "top-level", visible in the blocked cookies section in the request's cookies tab:

https://i.stack.imgur.com/tTINd.png

The provided code selectively intercepts responses from next-auth to enhance efficiency and updates the cookies to include a SameSite=None attribute, preventing blockages from Chromium.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Employ the next-intl library in a non-react component scenario

Is there a way to utilize next-intl outside of a React component? Currently, I am obtaining the t by utilizing the hook useTranslations, and then passing its instance to my function: function formatFoo(t, foo) { if .... t('bar'); } ...

Discover the best way to utilize useEffect on the server within Next.JS 14!

How can I effectively implement the useEffect functionality in Next.JS server components? I attempted to use useEffect on the server side but it was unsuccessful. Are there alternative hooks that can be utilized on the server side? If not, what is the bes ...

Tips for modifying the creation of NextJS route handler request object

Our Openlitespeed web server is causing issues with the parameter being sent to construct the request object in NextJS, leading to an error. import { type NextRequest } from 'next/server'; export function GET( request : NextRequest, { pa ...

Retrieving information from the API to populate a child component in Next.js

I have been developing a header component and here's the code snippet: import style from '../../styles/header.css'; import '../../styles/globals.css'; export default function Header({data}){ const [showMe, setShowMe] = useStat ...

Input fields in Next.js are experiencing issues with undefined props

Having some trouble creating a SearchBar feature that updates the "value" prop with user input. Struggling with getting the value and changeInput props to work properly, they keep returning as undefined. Any assistance would be greatly appreciated! cons ...

I'm facing an issue with SSRProvider in my NextJs application

My application is developed using NextJs and Typescript, utilizing the react-bootstrap library for creating components. I am facing an issue where I keep receiving an error message stating that When server rendering, you must wrap your application in an &l ...

Encountering a hydration error with the useResponsive hook in Nextjs Material UI

I am facing an issue with a useResponsive hook that relies on useMediaQuery from the Material-UI library. While using Next.js with app router, the initial value of the hook returns false and then transitions to true, causing a hydration mismatch. How can I ...

Having trouble capturing screenshots with PuppeteerJS?

I've encountered an issue while working with Puppeteer to capture screenshots from a provided URL. The code I have below doesn't seem to be functioning properly. It keeps showing the error message: [0] Error: Protocol error (Emulation.setDeviceM ...

Can components be SSGed individually rather than entire pages?

I am currently working with Next.js and I am wondering if there is a way to statically generate and display the database values in the header and footer components used across all pages. While getStaticProps can generate pages statically, it doesn't ...

How can I pass my cookie token in a Next.js server-side component request?

My Next.js version is 14.1.0 and I am currently using the App router. async function Page() { const dataPromise: Promise<any> = getData(); const data = await dataPromise; console.log('data: ', data); return ( .... ); } The ge ...

Utilize NPM package exclusively for server-side rendering (SSR) within a Next.js application

I'm currently attempting to incorporate a private NPM module exclusively during the initial page load when rendering is taking place on the server. Despite using the code below, I am noticing that my package still appears in chunks in client.html when ...

Looking to implement Socket.io in a Next.js and Node.js application to send a targeted socket emit to a particular user

I've been working on this issue and have tried various methods, but haven't had any luck so far. Despite reading through a lot of documentation and posts, I can't seem to figure it out. What I need is for a message sent to a specific user ( ...

Creating a fixed sidebar that remains visible while scrolling in Next.js

Currently, I am faced with the challenge of implementing two components - a feed and a sidebar. The sidebar contains more content than it can display at once, so I want it to be able to overflow. My goal is to have the sidebar scroll along with the content ...

Alert: The text content did not align. Server indicated as "0" while client indicated as "1"

Using next js to develop the cart feature, I decided to store all cart items in localStorage. Below is how I implemented it: import React, { createContext, useContext, useState, useEffect } from 'react'; import { toast } from 'react-hot-toas ...

Executing the callback function

I am facing a situation where I have a Modelmenu nested within the parent component. It is responsible for opening a modal window upon click. Additionally, there is a child component in the same parent component that also needs to trigger the opening of a ...

When working with Function components in NextJS, it's important to note that they cannot be assigned refs directly. If you're trying to access a ref within a Function component, you

I'm having an issue with wrapping a card component using the Link component from 'next/link'. Instead of redirecting me to the desired link when I click the card, I receive a warning that says 'Function components cannot be given refs. ...

Leveraging the NextAuth hooks, employ the useSession() function within the getServerSideProps

I'm currently working on retrieving data from my server based on the user who is logged in. I am utilizing Next-Auth and usually, I can easily obtain the session by calling: const { data: session } = useSession(); In a functional component, this work ...

Issue with locating .env file in GitHub CI Docker environment

Looking to deploy my Next.JS app using Docker and GitHub CI. The actions are running as expected, but I'm facing an issue with the .env.production file not being found when referenced in the Dockerfile. I attempted renaming the file to .env or other ...

When I send data using axios, I receive the response in the config object instead of the data

Currently, my web app is being developed using NextJS NodeJS and Express. I have set up two servers running on localhost: one on port 3000 for Next and the other on port 9000 for Express. In the app, there is a form with two input fields where users can e ...

Creating a flexible route path with additional query parameters

I am facing a challenge in creating a unique URL, similar to this format: http://localhost:3000/boarding-school/delhi-ncr However, when using router.push(), the dynamic URL is being duplicated like so: http://localhost:3000/boarding-school/boarding-school ...