Skip to content

Latest commit

 

History

History
146 lines (107 loc) · 4.45 KB

File metadata and controls

146 lines (107 loc) · 4.45 KB
title
Authentication

Zero uses a JWT-based flow to authenticate connections to zero-cache.

Frontend

During login:

  1. Your API server creates a JWT and sends it to your client.
  2. Your client constructs a Zero instance with this token by passing it to the auth option.
When you set the `auth` option you must set the `userID` option to the same value that is present in the `sub` field of the token.
const zero = new Zero({
  ...,
  auth: token, // your JWT
  userID, // this must match the `sub` field from `token`
});

Server

For zero-cache to be able to verify the JWT, one of the following environment variables needs to be set:

  1. ZERO_AUTH_SECRET - If your API server uses a symmetric key (secret) to create JWTs then this is that same key.
  2. ZERO_AUTH_JWK - If your API server uses a private key to create JWTs then this is the corresponding public key, in JWK format.
  3. ZERO_AUTH_JWKS_URL - Many auth providers host the public keys used to verify the JWTs they create at a public URL. If you use a provider that does this, or you publish your own keys publicly, set this to that URL.

Refresh

The auth parameter to Zero can also be a function:

const zero = new Zero({
  ...,
  auth: async () => {
    const token = await fetchNewToken();
    return token;
  },
  userID,
});

In this case, Zero will call this function to get a new JWT if verification fails.

Client-Side Data Storage

Zero stores client-side data in IndexedDB by default, but this is customizable with the kvStore parameter:

const zero = new Zero({
  // Store data in React Native's SQLite database
  // See https://github.com/Braden1996/react-native-replicache
  kvStore: createReplicacheReactNativeOPSQLiteKVStore,
});

const zero = new Zero({
  // Store data in memory, it disappears on refresh
  kvStore: 'mem',
});

Because multiple users can share the same browser, Zero requires that you provide a userID parameter on construction:

const zero = new Zero({
  ...,
  userID: "user-123",
});

Zero stores each user's data in a different IndexedDB instance. This allows users to quickly switch between multiple users and accounts without resyncing.

<Note emoji="🧑‍🏫" type="warning" heading="userID is not a security boundary" slug="user-id-is-not-a-security-boundary"

All users that have access to a browser profile have access to the same IndexedDB instances. There is nothing that Zero can do about this – users can just open the folder where the data is stored and look inside it.

If your application is unauthenticated, or if you don't need fast user switching, you can just set userID to a constant like anon or guest:

const zero = new Zero({
  ...,
  userID: "anon",
});

Alternately, if you have more than one set of Zero data per-user (i.e., for different apps in the same domain), you can additonally use the storageKey parameter:

const zero = new Zero({
  ...,
  userID: "user-123",
  storageKey: "my-app",
});

If specified, storageKey is concatenated along with userID and other internal Zero information to form a unique IndexedDB database name.

Logging Out

When a user logs out, you should consider what should happen to the synced data.

If you do nothing, the synced data will be left on the device. The next login will be a little faster because Zero doesn't have to resync that dta from scratch. But also, the data will be left on the device indefinitely which could be undesirable for privacy and security.

If you instead want to clear data on logout, Zero provides the dropAllDatabases function:

import {dropAllDatabases} from '@rocicorp/zero';

// Returns an object with:
// - The names of the successfully dropped databases
// - Any errors encountered while dropping
const {dropped, errors} = await dropAllDatabases();

Permissions

Any data placed into your JWT (claims) can be used by permission rules on the backend.

const isAdminRule = (decodedJWT, {cmp}) => cmp(decodedJWT.role, '=', 'admin');

See the permissions section for more details.

Examples

See zbugs or hello-zero.