openapi-ts / openapi-typescript

Generate TypeScript types from OpenAPI 3 specs
https://openapi-ts.dev
MIT License
5.92k stars 470 forks source link

Support cookie parameters #1771

Open MicahParks opened 4 months ago

MicahParks commented 4 months ago

Description

My OpenAPI specification contains parameters with values are located in cookies. It would be most convenient if this project wrote specified cookies to outgoing requests.

I saw https://github.com/openapi-ts/openapi-typescript/issues/1689 was closed and wanted an open issue for tracking.

When the openapi-typescript client is running in my Next.js project under a file with "use client" the web browser cookies are sent along :+1:

When the openapi-typescript client is running on server side Next.js code, no cookies are sent along with the request, even when specified.

Proposal

Cookies that are specified for a request are written to outgoing requests. If a cookie under that name already exists, it is overwritten if specified. In the case of the openapi-typescript client running under a file with "use client" (in the web browser), supplying the value of null (or similar) for a specified cookie name will allow a type-safe way to convey the meaning "use the web browser's value for this cookie"

Alternatively, docs and an example on how to do this via middleware would be wonderful, I am not very TypeScript savvy.

Checklist

kerwanp commented 3 months ago

Hey @MicahParks! It seems to be specifically related to Next.js.

When you use fetch from the client, the request will be made by the browser and the cookies will be sent along.

When you use fetch from the server, the request will be made by the server and the cookies will not be sent along.

This is a totally normal behavior, forwarding cookies automatically could result in hard to spot issues and security issues. (ex: forwarding authorization cookie to a third party api).

I advise you to use two distinct openapi-fetch client, one for the server and one for the client. And use a middleware to forward the cookies you cant by using the cookies function.

MicahParks commented 3 months ago

@kerwanp are you sure that this is unique to Next.js?

The below snippet uses the cookies function and runs on the Next.js server side. It is supposed to to pass the cookies from the web browser's request to the external Golang API. I can log the value of cookies().get(CookieAccount)?.toString() and it is as expected. However, the value is not include on the request to the external Golang API using openapi-typescript.

    const {data, error} = await GET("/signup/checkout-products", {
      params: {
        cookie: {"account": cookies().get(CookieAccount)?.toString() || ""},
      },
      next: {revalidate: 3600},
    })

It seems that populating the cookie attribute in the params object has no effect. Given that the cookie attribute is required in the OpenAPI specification, populating the cookie attribute is required for the TypeScript to compile due to the strong typing added. Therefore, it seems it is required to populate the cookie attribute, but ineffectual to do so.

If a middleware is required, I would suggest

  1. Remove the typing requiring the cookie attribute in params object.
  2. Add an example to the documentation that adds a cookie to an outgoing OpenAPI request.

If a middleware is not required, perhaps my original proposal may be considered. Please note that automatically forwarding cookies is not in the original proposal.

ayuhito commented 2 months ago

Remove the typing requiring the cookie attribute in params object.

I'm in favour of this since I tried to migrate to openapi-fetch and was blocked by the typing of cookies.

If I have HttpOnly cookies, then cookies are managed by the browser and are inaccessible by JavaScript for security. I can't tell the current TS client that these cookies are already being sent.

ex: forwarding authorization cookie to a third party api

Usually shouldn't happen unless you opt into this manually with credentials: include due to CORS or you've configured your SameSite attribute an insecure way.