Graphql-engine: Allow auth webhook to set cookies on response

Created on 25 May 2019  路  7Comments  路  Source: hasura/graphql-engine

Hasura does not currently (unless I'm doing something wrong) forward the Set-Cookie header from auth webhooks. This issue is similar to but different from #1654

Use cases:

  • Setting a tracking cookie on unauthenticated requests
  • Resetting cookie maxAge on each request. This would be very useful for cookies that expire within a set, short amount of time.

One option would be to forward the Set-Cookie header set by auth webhook to the response.

Another, more explicit option would be for the webhook to explicitly respond with a cookies object, and for those to be set on the response.

Here are two possible syntaxes for the auth webhook response:

{
    "X-Hasura-User-Id": "25",
    "X-Hasura-Role": "user",
    "X-Hasura-Is-Owner": "true",
    "X-Hasura-Custom": "custom value",
    "Cookies": {
        "<cookie-name>": {
            "Value": "<cookie-value>",
            "Expires": "<date>"
            "Max-Age": <non-zero-digit>,
            "Domain": "<domain-value>",
            "Path": "<path-value>",
            "Secure": <boolean>,
            "HttpOnly": <boolean>,
            "SameSite": "<Strict/Lax>"
        }
    },
    "Cookies": [
        {
            "Name": "<cookie-name>",
            "Value": "<cookie-value>",
            "Expires": "<date>"
            "Max-Age": <non-zero-digit>,
            "Domain": "<domain-value>",
            "Path": "<path-value>",
            "Secure": <boolean>,
            "HttpOnly": <boolean>,
            "SameSite": "<Strict/Lax>"
        }
    ]
}

Another, even more general purpose way would be to allow a special headers property. This would allow the webhook to set any header. Example syntaxes:

{
    "X-Hasura-User-Id": "25",
    "X-Hasura-Role": "user",
    "X-Hasura-Is-Owner": "true",
    "X-Hasura-Custom": "custom value",
    "Response-Headers": [
        {
            "name": "Set-Cookie",
            "value": "<cookie-name>=<cookie-value>; Expires: <date>; Max-Age: <non-zero-digit>; Domain: <domain-value>; Path: <path-value>; Secure: <boolean>; HttpOnly: <boolean>; SameSite: <Strict/Lax>",
        }
    ],
    "Response-Headers": [
        "Set-Cookie: <cookie-name>=<cookie-value>; Expires: <date>; Max-Age: <non-zero-digit>; Domain: <domain-value>; Path: <path-value>; Secure: <boolean>; HttpOnly: <boolean>; SameSite: <Strict/Lax>",
    ]
}
server quickfix enhancement high

Most helpful comment

This issue is critical to being able to fully use auth webhook securely (storing token in cookie instead of localStorage). Will this be addressed ever?

All 7 comments

@ecthiender @shahidhk Makes sense to me. Do you see any issues?

Would it be possible to have any visibility into this feature? Hasura is great. Not having access to cookies as an authentication mechanism is frustrating. I see that you may not want to pile too much into the auth webhook, but you are going to get a lot of feature requests there since it's the main mechanism to auth/filter/control/manipulate/monitor all the requests.

This issue is critical to being able to fully use auth webhook securely (storing token in cookie instead of localStorage). Will this be addressed ever?

@pcmaffey it seems to be fixed with https://github.com/hasura/graphql-engine/pull/2305
(didn't test it myself)

@fpieper As noted in the OP, this is different issue. Have tested and cookie headers aren't forwarded from auth webhook.

I ended up just making a merged Graphql schema that just did the same thing (validated the token and setting the cookie). Since merged schemas forward response cookies to the client, you can get websocket cookies, it's just an extra hoop. On the plus side, it makes the auth webhook very small (just examine the session token and accept or reject).

So my above solution works, but it comes with significant increased complexity, especially at the service level. If you want just a single server to perform auth and your business logic, and you want that server to have e.g. graphql derived code generation, then you're stuck with a chicken and egg problem, where the server cannot be started before hasura because it supplies a merged graphql schema, but the server needs hasura started to build its schema-derived sdk. It would be really great to get this feature in, my workaround is not great.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hooopo picture hooopo  路  3Comments

tirumaraiselvan picture tirumaraiselvan  路  3Comments

Fortidude picture Fortidude  路  3Comments

leoalves picture leoalves  路  3Comments

shahidhk picture shahidhk  路  3Comments