adding cookies to api route response [simple result] (#5060)

* adding cookies to the an api route response, also when returning a simple result

* in dev server, convert a simple endpoint result into a response object

Co-authored-by: AirBorne04 <unknown>
Co-authored-by: AirBorne04 <>
Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
Daniel 2022-10-18 15:52:49 +02:00 committed by GitHub
parent 04ce7f4e5c
commit 5923dd77c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 88 additions and 38 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
api routes: adding cookies to the response, also when returning a simple result

View file

@ -11,14 +11,12 @@
"astro": "astro",
"server": "node dist/server/entry.mjs"
},
"devDependencies": {},
"dependencies": {
"astro": "^1.5.0",
"svelte": "^3.48.0",
"@astrojs/svelte": "^1.0.2",
"@astrojs/node": "^2.0.0",
"concurrently": "^7.2.1",
"lightcookie": "^1.0.25",
"unocss": "^0.15.6",
"vite-imagetools": "^4.0.4"
}

View file

@ -28,6 +28,7 @@ async function get<T>(
): Promise<T> {
const response = await fetch(`${getOrigin(incomingReq)}${endpoint}`, {
credentials: 'same-origin',
headers: incomingReq.headers,
});
if (!response.ok) {
// TODO make this better...

View file

@ -1,7 +0,0 @@
import lightcookie from 'lightcookie';
export function isLoggedIn(request: Request): boolean {
const cookie = request.headers.get('cookie');
const parsed = lightcookie.parse(cookie);
return 'user-id' in parsed;
}

View file

@ -1,10 +1,9 @@
import { APIContext } from 'astro';
import lightcookie from 'lightcookie';
import { userCartItems } from '../../models/session';
export function get({ request }: APIContext) {
let cookie = request.headers.get('cookie');
let userId = cookie ? lightcookie.parse(cookie)['user-id'] : '1'; // default for testing
export function get({ cookies }: APIContext) {
let userId = cookies.get('user-id').value;
if (!userId || !userCartItems.has(userId)) {
return {
body: JSON.stringify({ items: [] }),
@ -23,11 +22,10 @@ interface AddToCartItem {
name: string;
}
export async function post({ request }: APIContext) {
export async function post({ cookies, request }: APIContext) {
const item: AddToCartItem = await request.json();
let cookie = request.headers.get('cookie');
let userId = lightcookie.parse(cookie)['user-id'];
let userId = cookies.get('user-id').value;
if (!userCartItems.has(userId)) {
userCartItems.set(userId, new Map());

View file

@ -2,9 +2,8 @@
import Header from '../components/Header.astro';
import Container from '../components/Container.astro';
import { getCart } from '../api';
import { isLoggedIn } from '../models/user';
if (!isLoggedIn(Astro.request)) {
if (!Astro.cookies.get('user-id').value) {
return Astro.redirect('/');
}

View file

@ -11,6 +11,32 @@ import Container from '../components/Container.astro';
font-size: 36px;
}
</style>
<script type="module" is:inline>
document.addEventListener('DOMContentLoaded', () => {
console.log('loaded');
document.querySelector('form').addEventListener('submit', (e) => {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
const data = Object.fromEntries(formData);
fetch('/login.form.async', {
method: 'POST',
body: JSON.stringify(data),
})
.then((res) => res.json())
.then((data) => {
document.querySelector("#result").innerHTML = "Progressive login was successful! you will be redirected to the store in 3 seconds";
setTimeout(
() => location.href = "/",
3000
);
});
});
});
</script>
</head>
<body>
<Header />
@ -26,6 +52,7 @@ import Container from '../components/Container.astro';
<input type="submit" value="Submit" />
</form>
<div id="result"></div>
</Container>
</body>
</html>

View file

@ -0,0 +1,16 @@
import { APIContext, APIRoute } from 'astro';
export const post: APIRoute = ({ cookies, params, request }: APIContext) => {
// add a new cookie
cookies.set('user-id', '1', {
path: '/',
maxAge: 2592000,
});
return {
body: JSON.stringify({
ok: true,
user: 1,
}),
};
};

View file

@ -1,9 +0,0 @@
export function post(params, request) {
return new Response(null, {
status: 301,
headers: {
Location: '/',
'Set-Cookie': 'user-id=1; Path=/; Max-Age=2592000',
},
});
}

View file

@ -0,0 +1,16 @@
import { APIContext } from 'astro';
export function post({ cookies, params, request }: APIContext) {
// add a new cookie
cookies.set('user-id', '1', {
path: '/',
maxAge: 2592000,
});
return new Response(null, {
status: 301,
headers: {
Location: '/',
},
});
}

View file

@ -9,7 +9,7 @@ import type { LogOptions } from '../logger/core.js';
import type { RouteInfo, SSRManifest as Manifest } from './types';
import mime from 'mime';
import { getSetCookiesFromResponse } from '../cookies/index.js';
import { attachToResponse, getSetCookiesFromResponse } from '../cookies/index.js';
import { call as callEndpoint } from '../endpoint/index.js';
import { consoleLogDestination } from '../logger/console.js';
import { error } from '../logger/core.js';
@ -236,10 +236,14 @@ export class App {
}
const bytes = this.#encoder.encode(body);
headers.set('Content-Length', bytes.byteLength.toString());
return new Response(bytes, {
const response = new Response(bytes, {
status: 200,
headers,
});
attachToResponse(response, result.cookies);
return response;
}
}
}

View file

@ -13,6 +13,7 @@ type EndpointCallResult =
type: 'simple';
body: string;
encoding?: BufferEncoding;
cookies: AstroCookies;
}
| {
type: 'response';
@ -109,5 +110,6 @@ export async function call(
type: 'simple',
body: response.body,
encoding: response.encoding,
cookies: context.cookies,
};
}

View file

@ -5,7 +5,7 @@ import type { AstroSettings, ManifestData } from '../@types/astro';
import { DevelopmentEnvironment, SSROptions } from '../core/render/dev/index';
import { Readable } from 'stream';
import { getSetCookiesFromResponse } from '../core/cookies/index.js';
import { attachToResponse, getSetCookiesFromResponse } from '../core/cookies/index.js';
import { call as callEndpoint } from '../core/endpoint/dev/index.js';
import {
collectErrorMetadata,
@ -378,8 +378,14 @@ async function handleRoute(
if (computedMimeType) {
contentType = computedMimeType;
}
res.writeHead(200, { 'Content-Type': `${contentType};charset=utf-8` });
res.end(result.body);
const response = new Response(result.body, {
status: 200,
headers: {
'Content-Type': `${contentType};charset=utf-8`,
},
});
attachToResponse(response, result.cookies);
await writeWebResponse(res, response);
}
} else {
const result = await renderPage(options);

View file

@ -260,7 +260,6 @@ importers:
'@astrojs/svelte': ^1.0.2
astro: ^1.5.0
concurrently: ^7.2.1
lightcookie: ^1.0.25
svelte: ^3.48.0
unocss: ^0.15.6
vite-imagetools: ^4.0.4
@ -269,7 +268,6 @@ importers:
'@astrojs/svelte': link:../../packages/integrations/svelte
astro: link:../../packages/astro
concurrently: 7.4.0
lightcookie: 1.0.25
svelte: 3.52.0
unocss: 0.15.6
vite-imagetools: 4.0.11
@ -13805,10 +13803,6 @@ packages:
type-check: 0.4.0
dev: true
/lightcookie/1.0.25:
resolution: {integrity: sha512-SrY/+eBPaKAMnsn7mCsoOMZzoQyCyHHHZlFCu2fjo28XxSyCLjlooKiTxyrXTg8NPaHp1YzWi0lcGG1gDi6KHw==}
dev: false
/lilconfig/2.0.6:
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
engines: {node: '>=10'}