Problems with AWS Amplify, Next.js and authenticated SSR

Viewed 1678

I've got a Next.js application that uses AWS Cognito userpools for authentication. I have a custom UI and am using the aws-amplify package directly invoking signIn/signOut/etc... in my code. (I previously used the AWS Hosted UI and had the same problem set out below - I hoped switching and digging into the actual APIs who reveal my problem but it hasn't)

Everything in development (running on localhost) is working correctly - I'm able to login and get access to my current session both in a page's render function using

import { Auth } from 'aws-amplify';
...
export default const MyPage = (props) => {
    useEffect(async () => {
        const session = await Auth.currentSession();
        ...
    }
    ...
}

and during SSR

import { withSSRContext } from 'aws-amplify';
...
export async function getServerSideProps(context) {
    ...
    const SSR = withSSRContext(context);
    const session = await SSR.Auth.currentSession();
    ...
}

However, when I deploy to AWS Amplify where I run my staging environment, the call to get the current session during SSR fails. This results in the page rendering as if the user is not logged in then switching when the client is able to determine that the user is in fact logged in.

Current Hypothesis - missing cookies(??):

I've checked that during the login process that the AWS cookies are being set correctly in the browser. I've also checked and devtools tells me the cookies are correctly being sent to the server with the request.

However, if I log out context.req.headers inside getServerSideProps in my staging environment, the cookie header is missing (whereas in my dev environment it appears correctly). If this is true, this would explain what I'm seeing as getServerSideProps isn't seeing my auth tokens, etc... but I can't see why the cookie headers would be stripped?

Has anyone seen anything like this before? Is this even possible? If so, why would this happen? I assume I'm missing something, e.g. config related, but I feel like I've followed the docs pretty closely - my current conf looks like this

Amplify.configure({
    Auth: {...}
    ssr: true
});

Next.js version is 11.1.2 (latest)

Any help very much appreciated!

4 Answers

You have to use Next@11.0.0 to use getServerSideProps, withSSRContext and Auth module in production.

I had same issue. My solution was that disconnect a branch has an authentication problem once and reconnect the branch.

What are your build settings? I guess you are using next build && next export in which case this getServerSideProps shall not work. See https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features

To use SSR with AWS amplify see https://docs.aws.amazon.com/amplify/latest/userguide/server-side-rendering-amplify.html#redeploy-ssg-to-ssr or consider deploying on a node server that is actually a server that you can start with next start like AWS EC2 or deploy on Vercel.

Otherwise if you use next export have to make do with client side data fetch only with client side updates only and cannot use dynamic server side features of nextjs.

One reason for context.req.headers not having any cookie in it is because CloudFront distribution is not forwarding any cookies.

This ā€œCloudFront Behaviourā€ can be changed in two ways:

  1. Forward all cookies, OR
  2. Forward specified cookies (i.e. array of cookie names)

To change the behaviour, navigate to CloudFront on AWS console > Distributions > your_distribution > Behaviors Tab.

Then Edit existing or Create new behaviour > Change cookies settings (for example set it to "All")

cloudfront-cookie-behaviour

Related