aws-amplify / amplify-hosting

AWS Amplify Hosting provides a Git-based workflow for deploying and hosting fullstack serverless web applications.
https://aws.amazon.com/amplify/hosting/
Apache License 2.0
460 stars 116 forks source link

NextJS getServerSideProps() missing cookies #2723

Open tjohnwu opened 2 years ago

tjohnwu commented 2 years ago

Before opening, please confirm:

JavaScript Framework

Next.js (tried with both 11 and 12)

Amplify APIs

Not applicable

Amplify Categories

No response

Environment information

``` System: OS: macOS 11.6.2 CPU: (8) x64 Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz Memory: 56.79 MB / 16.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.14.0 - /usr/local/bin/node Yarn: 1.22.17 - /usr/local/bin/yarn npm: 8.3.1 - /usr/local/bin/npm Browsers: Brave Browser: 98.1.35.104 Chrome: 99.0.4844.51 Firefox: 97.0.2 Safari: 15.2 npmGlobalPackages: @aws-amplify/cli: 7.6.4 corepack: 0.10.0 eas-cli: 0.4.3 expo-cli: 4.0.13 expo: 39.0.5 gatsby-cli: 3.7.1 graphql: 15.4.0 lerna: 4.0.0 mocha: 9.1.3 n: 7.5.0 npm: 8.3.1 ts-node: 10.4.0 tslint: 6.1.3 typescript: 4.5.2 ```

Describe the bug

When using getServerSideProps() in my NextJS project, I am unable to grab the cookies from the header.

When doing a clientside request with fetch() the cookies work fine.

This also works fine on my local machine through yarn dev.

Is there something special I have to do to use cookies in getServerSideProps()?

context.req.headers.cookies and context.req.cookies are both undefined.

Expected behavior

On getServerSideProps() we should be able to retrieve the cookies of the user

Reproduction steps

  1. Attach cookies to the url
  2. Go to a route that uses getServerSideProps(). This should automatically send the cookies with the request.
  3. Try to read the cookies in getServerSideProps() but shows up as undefined

Code Snippet

// Put your code below this line.

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

tjohnwu commented 2 years ago
export const getServerSideRedirect = async (context) => {
  const token = context.req?.cookies?.token
  console.log('redirect token: ', token)
  const pathName = context.resolvedUrl
  const newUrl = await getRedirectUrl(token, pathName)
  console.log(newUrl)
  if (newUrl) {
    return {
      redirect: {
        destination: newUrl,
        permanent: false,
      },
    }
  }

  return {
    props: {},
  }
}
chrisbonifacio commented 2 years ago

Hi @tjohnwu 👋 thanks for raising this issue. Have you enabled ssr in your app by configuring Amplify like so?

import { Amplify } from "aws-amplify";
import awsConfig from "../src/aws-exports.js"

Amplify.configure({
  ...awsConfig,
  ssr: true,
});

Also, please share the contents of your package.json file. Mostly need to see the build script for your app to see whether it's running next build (both SSR and SSG) or next build && next export (only SSG)

For more information: https://docs.aws.amazon.com/amplify/latest/userguide/server-side-rendering-amplify.html

tjohnwu commented 2 years ago

Here is the snippet from my package.json

{
  "name": "game",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "format": "prettier --write ."
  },

Yes I have Amplify.configure({}); in my _app.tsx .

It looks like there is something on the cloudfront side that is dropping my cookies from the request to getServerSideProps(). On a development build on my local machine, everything works fine.

Client (has cookies) -> SSR (no cookies found, can't forward cookies) -> Backend Service (no cookies)

It's not just my app specific token, the getServerSideProps() lambda on AWS is also missing my google analytics tokens.

joaopgsilva commented 2 years ago

Hey @tjohnwu I am facing a similar issue, but by going to the Cloudfront distribution associated with the Amplify deployment into the Behaviours tab you will see that for api/* and for the Default (*) when changing to Legacy cache settings and Cookies to All you will see that cookies will show up. Then one thing I am seeing now is that after each Amplify deployment the Cloudfront distribution is invalidated and rewritten so this setting goes back to what it was previously.

chrisbonifacio commented 2 years ago

@tjohnwu it sounds like what you're experiencing is similar to @joaopgsilva 's issue. Can you try their solution?

Because this sounds more like a hosting issue than a JS one, I'm going to transfer this over to the hosting repo for better feedback and support on a more permanent solution.

joaopgsilva commented 2 years ago

Although my solution allowed for cookies to be passed, these cookies are then cached, causing unexpected responses. So it is not a valid solution. Using Amplify to deploy I am unable to get cookies on getServersideProps or inside any API call.

pjaws commented 2 years ago

Also experiencing this issue.

Vivek205 commented 2 years ago

+1

0xNoxETH commented 2 years ago

@joaopgsilva's answer fixed the issue for me. The problem was actually the Cloudfront cache, after fixing it the API responses were just fine.

  1. Go to Cloudfront, open the distribution auto-created by Amplify
  2. Click Behaviors
  3. Edit the behaviors with the path pattern api/* and Default (*), set Cookies to All image
arapl3y commented 2 years ago

While @0xNoxETH's solution works, the distribution's behaviors config seems to reset on every deployment...

kirkmin-clearmarket commented 1 year ago

Having the same issue with amplify not sending cookies server side. We use cookies to store information about the user, and update our UI with appropriate texts. But since this is information is not being sent, it's resulting in a minified react error #418, which states that "Hydration failed because the initial UI does not match what was rendered on the server." I've also been able to go to Cloudfront to update the cookies settings manually. But this is overriden on every deployment, and is not a maintainable deal solution...Any ideas on how we should proceed?

benprofitt commented 1 year ago

Having the same issue. Any progress on this?

icabetong commented 1 year ago

+1