How to access Fauna with GraphQL on the client without exposing secrets?

I’m referring to the Next.js with-graphql-faunadb example.

The queries to fauna [1] are called directly from a React component [2]. Won’t this cause the secret to leak since it’s client-side code? What’s the best way around this?

[1] https://github.com/vercel/next.js/blob/canary/examples/with-graphql-faunadb/graphql/api.js
[2] https://github.com/vercel/next.js/blob/canary/examples/with-graphql-faunadb/components/Hero.js

Brecht laid out most of an example for how to use

  1. very-short-lived, in-memory user tokens, along with
  2. refresh session tokens via secure HTTP-only cookies.

I am working on adapting this and using Apollo Client to call the native GraphQL endpoint directly from the front end, and adding apollo-link-rest to call login and refresh mutations served as serverless functions (sorry don’t have anything to share yet, just started a couple days ago!).

Note that this does also expose your login client secret, but the idea is that it only lives for 10 minutes or so.

The real solution is fauna accepting signed JWT’s, but that is said to be coming “soon”. In the mean time, Brecht’s answer on the topic hear is a good path to start taking (In my opinion) to be able to adapt to JWT once available.

Alternatively, here is an example of using secure HTTP-only cookies with a proxy GraphQL server. This is much simpler to implement email+password auth, but means that every query or mutation will also cost an additional serverless function call.

This was significantly influenced by the nextjs examples.

I use Cloudflare workers for this specific purpose. They’re designed for short CPU time operations in large quantities and fit perfectly for this use case.

I take the secret, encode it and store it in a JWT.

The problem is how do you use the JWT with Fauna. At the moment, you cannot do that straight from the client, and need some backend logic to get the secret from jwt, create new client, then execute a query. This can be additionally painful using GraphQL.

Brecht’s refresh cookie idea limits server logic to just login and refresh, and letting all queries be called from the client since token is allowed in memory.

1 Like

I just posted part 1 of an article that might help. It deals with using FaunaDB with Elm and GraphQL and illustrates the use of Roles and attribute-based access control to allow safe login. Its not a complete example showing all considerations, but might provide you some good pointers.

1 Like