-
Notifications
You must be signed in to change notification settings - Fork 9.1k
Multiple 'Set-Cookie' headers in one response #1237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
You can of course have multiple headers with the same name in your HTTP response, but it looks like OpenAPI 2.0 has no way of documenting that. The way shown by you doesn't work (a JSON or YAML object can have each key just once, and if you repeat one, most parsers will retain just one of them). I think it looks like the same with the current RC of OpenAPI 3.0 – while the handling of plural parameters changed (via (By the way, I think that Cookies should not be necessary in a Restful API – but the same applies to other headers too.) |
Per @darrelmiller - We have a way to capture this in the request but not in the response. @JohnnyNiu Is that sufficient for your use case? |
The |
@RobDolinMS Also, you can't have multiple
|
This comment was marked as outdated.
This comment was marked as outdated.
I'm interested in this issue for the purpose of using the |
I found this issue when looking for a way to represent the ability to have multiple occurrences of the same header. In my case, the number of occurrences is unknown, and so using an array seemed ideal. It almost works, except that
I was expecting it to generate multiple header entries like this,
But instead ends up with a comma-delimited list within a single field,
Would it be possible to fix so that |
@njr-11 How this headers are actually rendered is a function of the tool you are using, not the specification. I would suggest bringing this up with whatever tooling you are using. On the other hand, for HTTP headers that allow duplicate headers, the two forms you show are considered semantically equivalent. See https://tools.ietf.org/html/rfc7230#section-3.2.2 |
You definitively can, that is how the entire internet is built up. S5.1 specifies the user is sending the Set-Cookie header. Look in S3.1, there is a clear example of this being allowed if the server is sending it: |
This comment was marked as outdated.
This comment was marked as outdated.
It seems what RobDolinMS means is that |
@sunxia0 This PR is regarding the Set-Cookie header though. |
This still doesn't appear to be supported (3.0.3) |
It appears it is supported (see the use of |
Ah gotcha. I had tried |
Still, any plan to fix? |
Fix what? Nothing is broken. What behaviour are you expecting? |
How to send 2 cookies in one response? |
@karenetheridge The |
Unfortunately Set-Cookie is an exception to the rule of HTTP headers https://www.rfc-editor.org/rfc/rfc9110.html#section-5.3 I wonder if we could use a schema of type object to describe the returned cookie pairs. e.g. responses:
200:
description: ok
headers:
Set-Cookie:
schema:
type: object
properties
foo:
type: string
bar:
type: string This doesn't help terribly if you want to be able to describe the cookie attributes. Maybe this is a case for trying to invent an extension. responses:
200:
description: ok
headers:
Set-Cookie:
x-cookies-defn:
- name: bar
path: /
domain: example.com
- name: foo
path: /
domain: example.com |
So how to respond with accessToken + csrfToken + refreshToken in one response? |
Something like this? I may be missing something completely. I have never used an API that uses Set-Cookie, so I have no experience with it. Do you have any insight on why people build APIs that rely on Set-Cookie? responses:
200:
description: ok
headers:
Set-Cookie:
x-cookies-defn:
- name: accessToken
path: /
domain: example.com
- name: csrfToken
path: /
domain: example.com
- name: refreshToken
path: /
domain: example.com |
Cookies are set to store credentials, especially since they support HttpOnly flag that prevents from JS to access its contents. This is in order to mitigate XSS. |
@darrelmiller It's not so much that I want to build an API that relies on cookies, so much as I want to document an API that already does, or has to, use cookies. In particular, cookies are useful for session management, especially since as @razb-viola mentioned, they can be hidden from client-side (JavaScript) code entirely. Obviously, the kind of APIs we're talking about are primarily browser-facing, though they can be server-to-server as well.
|
@kbolino The CSRF token will be stored in a cookie - without HttpOnly flag - and then be sent in the header after read from JS. The HttpOnly flag is only for the accessToken itself (and refresh token). While reading it explicitly from the cookie using JS ensures no one trying to forge this request from an email or something. |
@razb-viola As long as the CSRF token is externally verifiable (e.g. by the server's state) then it shouldn't be a problem; you should still not trust |
Would it make sense to add |
I check in my server using hmac crypto mechanism - the user provides his CSRF token in the headers (after reading from the cookie explicitly), then the server takes the actual accessToken and run hmac on it, the result should be equal to the user provided CSRF token in the header. |
Why not? (Response headers to be precise*) |
Not response headers, response object :)
|
Why not use a It's certainly not the most elegant solution, but it's accurate (unless the cookies are always sent in a set order, in which case |
Could you write an example? |
@rafalkrupinski yes, but I'm realizing that there may be more to this than I initially thought. How much do you need to model the contents of each |
I thought cookies were identified with more than just their names, like domain, path or secure-only (they are for storage purposes), but the server SHOULD* only send one Set-Header with a given cookie name... So response cookies could be modelled with JSON Schema as an The example (the first one) responses:
200:
description: ok
headers:
Set-Cookie:
schema:
type: object
properties
foo:
type: string
bar:
type: string could be used, if it was specified by the OAS. Full definition for a cookie header value would look more like this: headers:
Set-Cookie:
schema:
type: object
properties
foo:
type: object
properties:
value:
type: $type
domain:
type: string
secure-only:
... But, except the value property the schema is constant, so the first example should be sufficient to model cookies. This is really a special case and re-purposing of JSON Schema, since the type doesn't even describe the header value, rather the cookie value, which is only a part of the header value, and we don't even model a JSON Object here. * Severs should send only one cookie with a given name - that's what the RFC says. SHOULD means that there might be exceptions 🤦 |
@rafalkrupinski yeah, this falls under "more complex than I had been thinking" - what is needed is an agreed-upon way of modeling the header contents with JSON Schema (which we don't have), at which point we could model potential values using an array. The I started a discussion on modeling headers in the OAS 4 "Moonwalk" SIG: and I already listed this issue as one of the motivations. If we can manage to model headers like that, we will backport it to 3.x if possible. Since it's not yet clear that that approach to modeling headers will be accepted into Moonwalk, I'm leaving issues like this open here for now. If it moves farther along, I might close this and others in favor of the Moonwalk discussion. |
Reviewing this, it really does seem to boil down to being able to model headers (including multiple values for a single header) properly, which we will be looking at for 3.3 (after a shorter 3.2 that is not tackling any problems this complex). The unusual restrictions on |
Multiple headers of the same name should be supported, by my reading of the spec.. at least, when I was in this area last year I was able to get it to work. However, splitting an individual header into separate keys is not specified, although we should be able to handle this as well. Therefore, I would expect you could do something like this (making the schema more complicated if you want to restrict what cookie names or fields you see):
Where the HTTP headers (in the HTTP response, serialized to text) contains:
would decode into the json data model like this:
Anyway, this is just a strawman; perhaps a different way of decoding these headers to json would be more appropriate (e.g. is the order of the fields in each header significant? perhaps so, where the cookie name is always first? in that case we may need an array of objects for each header). |
This comment was marked as spam.
This comment was marked as spam.
@karenetheridge why do we need to model these serialization differences? They are not relevant to the content AFAICT. |
I explicitly asked if they were significant; I did not assert that they were. |
@karenetheridge ah, I see what happened- I was referring to whether the headers were on different lines or not, but that was a misreading of what you are proposing... I think? You are just using an array for multiple values of the same header regardless of their arrangement across lines? I was not replying to the order question- which should remind me to quote the thing I'm replying to! In answer to that question, I'm not sure. RFC9110 does not say one way or the other AFAICT, but I don't know if there's a header that defines an order-sensitive parameter list. |
Is it possible to have multiple 'Set-Cookie' headers in one response? As is known there are two ways to set cookies header in the response:
- Having separated headers
- Folding into 1 header and using comma separated
The later way however is deprecated in (RFC6265)[http://www.rfc-editor.org/rfc/rfc6265.txt] and not supported by some latest browsers.
So that below can be valid:
The text was updated successfully, but these errors were encountered: