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:
parent
04ce7f4e5c
commit
5923dd77c1
14 changed files with 88 additions and 38 deletions
5
.changeset/silent-cougars-run.md
Normal file
5
.changeset/silent-cougars-run.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
api routes: adding cookies to the response, also when returning a simple result
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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());
|
||||
|
|
|
@ -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('/');
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
16
examples/ssr/src/pages/login.form.async.ts
Normal file
16
examples/ssr/src/pages/login.form.async.ts
Normal 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,
|
||||
}),
|
||||
};
|
||||
};
|
|
@ -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',
|
||||
},
|
||||
});
|
||||
}
|
16
examples/ssr/src/pages/login.form.ts
Normal file
16
examples/ssr/src/pages/login.form.ts
Normal 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: '/',
|
||||
},
|
||||
});
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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'}
|
||||
|
|
Loading…
Reference in a new issue