#Create a cookie from a component

14 messages · Page 1 of 1 (latest)

open ibex
#

I'm using appwrite as the backend so i need to create a cookie to store the session, and the cookie generates well, but it doesn't rise to the client, I'm using SSR

#
import {
    AppwriteEndpoint,
    AppwriteHostname,
    AppwriteProject,
    SsrHostname,
} from "@lib/appwrite";
import * as setCookie from "set-cookie-parser";
import { type AstroCookieSetOptions } from "astro";
if (Astro.request.method === "POST") {
    try {
        const data = await Astro.request.formData();
        const email = data.get("email");
        const password = data.get("password");
        const response = await fetch(
            `${AppwriteEndpoint}/account/sessions/email`,
            {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "X-Appwrite-Response-Format": "1.4.0",
                    "x-appwrite-project": AppwriteProject,
                },
                body: JSON.stringify({email, password}),
            },
        );
        const json = await response.json();
        if (json.code >= 400) {
            return new Response(JSON.stringify({ message: json.message }));
        }
        const ssrHostname = SsrHostname === "localhost" ? SsrHostname : "." + SsrHostname;
        const appwriteHostname = AppwriteHostname === "localhost" ? AppwriteHostname : "." + AppwriteHostname;
        const cookiesStr = (response.headers.get("set-cookie") ?? "").split(appwriteHostname).join(ssrHostname);
        const cookiesArray = setCookie.splitCookiesString(cookiesStr);
        const cookiesParsed = cookiesArray.map((cookie) =>setCookie.parseString(cookie));
        for (const cookie of cookiesParsed) {
            Astro.cookies.set(cookie.name, cookie.value, {
                domain: cookie.domain,
                secure: cookie.secure,
                sameSite: cookie.sameSite,
                path: cookie.path,
                maxAge: cookie.maxAge,
                httpOnly: cookie.httpOnly,
                expires: cookie.expires,
            });
        }
        return new Response(JSON.stringify({ json }));
    } catch (error) {}
}
#

this is my script

#

it generate a session in the server and the cookies, but the final cookies dont show in my browser, but if i console.log them they are on the server, how can i rise them?

dull knot
#

Astro.cookies is only available at the page level, there is a small note in the docs about it here:

Features that modify the Response headers are only available at the page level. (You can’t use them inside of components, including layout components.) By the time Astro runs your component code, it has already sent the Response headers and they cannot be modified.
https://docs.astro.build/en/guides/server-side-rendering/#on-demand-rendering-features

open ibex
#

so, how can i setup the cookie?

#

i dont get it

open ibex
#

but how can i catch that middleware?

#

for example i have this middleware

import { defineMiddleware } from "astro:middleware";
export const protectedRoutes = defineMiddleware(
  async (context, next) =>{
    const publicRoutes = [
        "/",
        "/auth",
        "/auth/login",
    ];

    const url = context.url.pathname;

    if (publicRoutes.includes(url)) {
        return next();
    }

    if (context.locals.account) {
        return next();
    }

    return Response.redirect(new URL("/auth", context.url), 302);

  })
#

@dull knot

dull knot
#

Do you mind explaining a bit more? What do you mean by catch?

open ibex
#

i mean like how should i write that middleware, by how can i tell the middleware to make cookie when i try to login

dull knot
#

I haven't used Middleware or auth very much but I would check url and then use data from the request (like user/pass) to attempt a login and either set the cookie or redirect