Return response from middleware

So I’m building a small full-stack application using Cloudflare Pages. It has a few small functions that fetch data etc and return it to the front-end, and also a middleware function that handles OAuth token exchange (made sense to me to put it there so that this can run before any of the other functions). The middleware looks something like this (removed most of the actual code):

export async function onRequestGet(context) {
    // Check if we received an access token in the Cookie header
    // If yes, use that token
    // If no, fetch a new one using client secret
    ...
    // Pass the access token to whatever function wants to run next
    context.data.accessToken = accessToken;
    return await context.next();
}

This works fine. However, I of course also want to return the access token to the client, so that it can then be included in the next function call made from the front-end.

I know how to do this, something like:

return Response.json(data, {
    headers: {
        'Set-Cookie': `access_token=${accessToken}; Max-Age=<some-age>; Path=/`
    }
});

But what I don’t know is how to return this response from the middleware function. That’s what would make sense to me, because I want to return that Set-Cookie header no matter what function is being called without having to set it in the Response in each of those functions.

I think I have to have this return statement in the middleware?

return await context.next();

That’s what passes the call along to the function that’s actually being called, right? And I can’t have two return statements (only the first one would actually happen), so I cannot also return a Response with a Set-Cookie header.

How does this “call stack” actually work? Does the response from the function being called get returned to the middleware, and then returned from there to the client? So can I somehow plug my cookie header in there? Or do I have to set that header in the Response in every function that might run after the middleware?

I think I figured it out myself…

I realized context.next() actually returns a Response (the promise from the function that was run after the middleware I think?), so I guess what I do is this?

context.data.accessToken = accessToken;
    const response = await context.next();
    // Add any response headers that should be set no matter what function is called
    // ...
    // Return the response with new headers added
    return response;

(Sorry for spamming, seems like I can’t edit my posts)

But if I do this:

export async function onRequestGet(context) {

    // ...

    let accessToken = getNewAccessToken();
    context.data.accessToken = accessToken;
    const response = await context.next();
    response.headers.set('Set-Cookie', `access_token=${accessToken}; Max-Age=<some-age>; Path=/`);
    return response;
}

…is accessToken guaranteed to still exist after the next function has run and returned its response? Functions only live as they’re being called, right? So could the middleware function “die” while the next function is executing, which would mean that once the response is returned accessToken might no longer exist in memory? Or is the middleware function guaranteed to exist until context.next() has been executed AND returned its response back to the middleware?

Multiple functions are actually bundled together as one Worker, so you can indeed store things in memory across the middlewares fine. Just dont try to store things in memory across requests.