Skip to content
This repository was archived by the owner on Jan 28, 2025. It is now read-only.

Commit 793f0a2

Browse files
authored
feat(nextjs-component): forward common headers such as authorization and host by default (#1660)
1 parent 67c280f commit 793f0a2

File tree

7 files changed

+136
-24
lines changed

7 files changed

+136
-24
lines changed

packages/e2e-tests/next-app/cypress/integration/api-routes.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ describe("API Routes Tests", () => {
1818
} else {
1919
expect(response.body).to.deep.equal({
2020
name: "This is a basic API route.",
21-
method: method
21+
method: method,
22+
body: ""
2223
});
2324
}
2425
});

packages/e2e-tests/next-app/cypress/integration/rewrites.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,5 +177,25 @@ describe("Rewrites Tests", () => {
177177
});
178178
});
179179
});
180+
181+
it("externally rewrites to /api/basic-api with correct method, body and forwarded auth headers", () => {
182+
cy.request({
183+
url: "/api/external-rewrite-internal-api",
184+
method: "POST",
185+
body: "blah",
186+
failOnStatusCode: false,
187+
headers: { Authorization: `Bearer 12345` }
188+
}).then((response) => {
189+
expect(response.status).to.equal(200);
190+
191+
// body should be the same as /api/basic-api
192+
expect(response.body).to.deep.equal({
193+
name: "This is a basic API route.",
194+
method: "POST",
195+
body: "blah",
196+
authorization: "Bearer 12345" // authorization header is forwarded via CF, and external rewrite should forward it as well
197+
});
198+
});
199+
});
180200
});
181201
});

packages/e2e-tests/next-app/next.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ module.exports = {
150150
{
151151
source: "/no-op-rewrite",
152152
destination: "/ssr-page"
153+
},
154+
{
155+
source: "/api/external-rewrite-internal-api",
156+
destination: "/api/basic-api"
153157
}
154158
];
155159
},

packages/e2e-tests/next-app/pages/api/basic-api.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ import { NextApiRequest, NextApiResponse } from "next";
33
type Data = {
44
name: string;
55
method: string | undefined;
6+
authorization: string | undefined;
7+
body: string;
68
};
79

810
export default (req: NextApiRequest, res: NextApiResponse<Data>) => {
911
res.setHeader("Content-Type", "application/json");
1012

1113
res.status(200).json({
1214
name: "This is a basic API route.",
13-
method: req.method
15+
method: req.method,
16+
authorization: req.headers.authorization,
17+
body: req.body
1418
});
1519
};

packages/serverless-components/nextjs-component/__tests__/custom-inputs.test.ts

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,11 @@ describe("Custom inputs", () => {
808808
"PUT",
809809
"PATCH"
810810
],
811+
forward: {
812+
cookies: "all",
813+
headers: ["Authorization", "Host"],
814+
queryString: true
815+
},
811816
"lambda@edge": {
812817
...(expectedInConfig["api/*"] &&
813818
expectedInConfig["api/*"]["lambda@edge"]),
@@ -844,6 +849,7 @@ describe("Custom inputs", () => {
844849
],
845850
forward: {
846851
cookies: "all",
852+
headers: ["Authorization", "Host"],
847853
queryString: true
848854
},
849855
compress: true,
@@ -869,6 +875,11 @@ describe("Custom inputs", () => {
869875
defaultTTL: 0,
870876
maxTTL: 31536000,
871877
allowedHttpMethods: ["HEAD", "GET"],
878+
forward: {
879+
cookies: "all",
880+
headers: ["Authorization", "Host"],
881+
queryString: true
882+
},
872883
"lambda@edge": {
873884
"origin-request":
874885
"arn:aws:lambda:us-east-1:123456789012:function:my-func:v1",
@@ -880,6 +891,11 @@ describe("Custom inputs", () => {
880891
minTTL: 0,
881892
defaultTTL: 0,
882893
maxTTL: 31536000,
894+
forward: {
895+
cookies: "all",
896+
headers: ["Authorization", "Host"],
897+
queryString: true
898+
},
883899
...expectedApiCacheBehaviour
884900
},
885901
"_next/image*": {
@@ -893,7 +909,15 @@ describe("Custom inputs", () => {
893909
forward: {
894910
headers: ["Accept"]
895911
},
896-
allowedHttpMethods: expect.any(Array)
912+
allowedHttpMethods: [
913+
"HEAD",
914+
"DELETE",
915+
"POST",
916+
"GET",
917+
"OPTIONS",
918+
"PUT",
919+
"PATCH"
920+
]
897921
},
898922
"static/*": {
899923
...customPageCacheBehaviours["static/*"],
@@ -975,18 +999,9 @@ describe("Custom inputs", () => {
975999
"arn:aws:lambda:us-east-1:123456789012:function:my-func:v1"
9761000
};
9771001

978-
// If path is api/*, then it has allowed HTTP methods by default
979-
if (pathName === "api/*") {
980-
cloudFrontInput[pathName]["allowedHttpMethods"] = [
981-
"HEAD",
982-
"DELETE",
983-
"POST",
984-
"GET",
985-
"OPTIONS",
986-
"PUT",
987-
"PATCH"
988-
];
989-
}
1002+
// we want to make sure that default behaviors are combined correctly
1003+
const apiCloudFrontInput = cloudFrontInput["api/*"];
1004+
delete cloudFrontInput["api/*"];
9901005

9911006
const expectedInput = {
9921007
origins: [
@@ -1002,7 +1017,12 @@ describe("Custom inputs", () => {
10021017
"arn:aws:lambda:us-east-1:123456789012:function:my-func:v1"
10031018
},
10041019
maxTTL: 31536000,
1005-
minTTL: 0
1020+
minTTL: 0,
1021+
forward: {
1022+
cookies: "all",
1023+
headers: ["Authorization", "Host"],
1024+
queryString: true
1025+
}
10061026
},
10071027
"_next/static/*": {
10081028
defaultTTL: 86400,
@@ -1024,13 +1044,19 @@ describe("Custom inputs", () => {
10241044
"PUT",
10251045
"PATCH"
10261046
],
1047+
forward: {
1048+
cookies: "all",
1049+
headers: ["Authorization", "Host"],
1050+
queryString: true
1051+
},
10271052
defaultTTL: 0,
10281053
"lambda@edge": {
10291054
"origin-request":
10301055
"arn:aws:lambda:us-east-1:123456789012:function:my-func:v1"
10311056
},
10321057
maxTTL: 31536000,
1033-
minTTL: 0
1058+
minTTL: 0,
1059+
...apiCloudFrontInput
10341060
},
10351061
"_next/image*": {
10361062
minTTL: 0,
@@ -1043,7 +1069,15 @@ describe("Custom inputs", () => {
10431069
forward: {
10441070
headers: ["Accept"]
10451071
},
1046-
allowedHttpMethods: expect.any(Array)
1072+
allowedHttpMethods: [
1073+
"HEAD",
1074+
"DELETE",
1075+
"POST",
1076+
"GET",
1077+
"OPTIONS",
1078+
"PUT",
1079+
"PATCH"
1080+
]
10471081
},
10481082
"static/*": {
10491083
defaultTTL: 86400,

packages/serverless-components/nextjs-component/__tests__/deploy.test.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,19 @@ describe.each`
310310
it("creates distribution", () => {
311311
expect(mockCloudFront).toBeCalledWith({
312312
defaults: {
313-
allowedHttpMethods: expect.any(Array),
313+
allowedHttpMethods: [
314+
"HEAD",
315+
"DELETE",
316+
"POST",
317+
"GET",
318+
"OPTIONS",
319+
"PUT",
320+
"PATCH"
321+
],
314322
forward: {
315-
queryString: true,
316-
cookies: "all"
323+
cookies: "all",
324+
headers: ["Authorization", "Host"],
325+
queryString: true
317326
},
318327
minTTL: 0,
319328
defaultTTL: 0,
@@ -346,6 +355,11 @@ describe.each`
346355
defaultTTL: 0,
347356
maxTTL: 31536000,
348357
allowedHttpMethods: ["HEAD", "GET"],
358+
forward: {
359+
cookies: "all",
360+
headers: ["Authorization", "Host"],
361+
queryString: true
362+
},
349363
"lambda@edge": {
350364
"origin-request":
351365
"arn:aws:lambda:us-east-1:123456789012:function:default-cachebehavior-func:v1",
@@ -371,7 +385,20 @@ describe.each`
371385
"origin-request":
372386
"arn:aws:lambda:us-east-1:123456789012:function:api-cachebehavior-func:v1"
373387
},
374-
allowedHttpMethods: expect.any(Array)
388+
allowedHttpMethods: [
389+
"HEAD",
390+
"DELETE",
391+
"POST",
392+
"GET",
393+
"OPTIONS",
394+
"PUT",
395+
"PATCH"
396+
],
397+
forward: {
398+
cookies: "all",
399+
headers: ["Authorization", "Host"],
400+
queryString: true
401+
}
375402
},
376403
"_next/image*": {
377404
minTTL: 0,
@@ -384,7 +411,15 @@ describe.each`
384411
forward: {
385412
headers: ["Accept"]
386413
},
387-
allowedHttpMethods: expect.any(Array)
414+
allowedHttpMethods: [
415+
"HEAD",
416+
"DELETE",
417+
"POST",
418+
"GET",
419+
"OPTIONS",
420+
"PUT",
421+
"PATCH"
422+
]
388423
}
389424
}
390425
}

packages/serverless-components/nextjs-component/src/component.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,13 @@ class NextjsComponent extends Component {
661661
"PUT",
662662
"PATCH"
663663
],
664+
forward: {
665+
headers: routesManifest.i18n
666+
? ["Accept-Language", "Authorization", "Host"]
667+
: ["Authorization", "Host"],
668+
cookies: "all",
669+
queryString: true
670+
},
664671
// lambda@edge key is last and therefore cannot be overridden
665672
"lambda@edge": {
666673
"origin-request": `${apiEdgeLambdaOutputs.arn}:${apiEdgeLambdaPublishOutputs.version}`
@@ -782,6 +789,11 @@ class NextjsComponent extends Component {
782789
defaultTTL: 0,
783790
maxTTL: 31536000,
784791
allowedHttpMethods: ["HEAD", "GET"],
792+
forward: {
793+
cookies: "all",
794+
headers: ["Authorization", "Host"],
795+
queryString: true
796+
},
785797
"lambda@edge": {
786798
"origin-response": `${defaultEdgeLambdaOutputs.arn}:${defaultEdgeLambdaPublishOutputs.version}`,
787799
"origin-request": `${defaultEdgeLambdaOutputs.arn}:${defaultEdgeLambdaPublishOutputs.version}`
@@ -850,7 +862,9 @@ class NextjsComponent extends Component {
850862
maxTTL: 31536000,
851863
...cloudFrontDefaults,
852864
forward: {
853-
headers: routesManifest.i18n ? ["Accept-Language"] : undefined,
865+
headers: routesManifest.i18n
866+
? ["Accept-Language", "Authorization", "Host"]
867+
: ["Authorization", "Host"],
854868
cookies: "all",
855869
queryString: true,
856870
...cloudFrontDefaults.forward

0 commit comments

Comments
 (0)