Auth

JWT login

Let your backend act on behalf of authenticated users while respecting their permissions - perfect for custom APIs and server-side logic.

Your client app is authenticated, but your backend needs to access user data too. JWT lets your server act as the user, with the same permissions and restrictions they'd have on the client.

Why JWT matters

API Key Problem: Server SDK with API key sees everything - all users, all data, all permissions ignored.

JWT Solution: Server SDK with JWT sees only what the user can see - same permissions, same restrictions, same security.

How JWT works

  1. User authenticates - Client app creates session with Nuvix
  2. Generate JWT - Client requests JWT token (expires in 15 minutes)
  3. Send to backend - Client includes JWT in API requests
  4. Server acts as user - Backend uses JWT to access user-permitted resources only
  5. Token expires - JWT automatically invalidates after 15 minutes or when session ends

Generate JWT on client

User must be authenticated first:

import { Client } from "@nuvix/client";

const nx = new Client()
    .setEndpoint('https://api.nuvix.in/v1')
    .setProject('<PROJECT_ID>');

// User must be logged in first
const jwt = await nx.account.createJWT();

// Send to your backend
await fetch('/api/user-data', {
    headers: { 'Authorization': `Bearer ${jwt.jwt}` }
});

Use JWT on server

Backend acts with user permissions:

import { Client } from "@nuvix/client";

// Create client with user's JWT
const nx = new Client()
    .setEndpoint('https://api.nuvix.in/v1')
    .setProject('<PROJECT_ID>')
    .setJWT(userJWT); // User's JWT from client

// Now server acts with user permissions
// Only returns data user can access
const documents = await client.schema('default').collection(
    'collection-id'
).find();

JWT vs API Key comparison

Same request, different results:

AuthenticationUser A seesUser B seesUser C sees
JWTOnly their dataOnly their dataOnly their data
API KeyEverythingEverythingEverything

Real example: User's personal data

Database with birthday records, each with different user permissions:

DocumentNameBirthdayPermissions
doc1Kevin2012-02-03read("user:user-a")
doc2Laura1999-09-22read("user:user-b")
doc3Bob1982-05-11read("user:user-c")

With JWT (user-a authenticated):

const nx = new Client().setJWT(userAJWT);
const docs = await client.schema('db').collection('birthdays').find();
// Returns: [Kevin's document only]

With API Key:

const nx = new Client().setKey(apiKey);
const docs = await client.schema('db').collection('birthdays').find();
// Returns: [Kevin, Laura, Bob documents] - Privacy violation!

When to use JWT

Use JWT when your backend needs to:

  • Access user-specific data only
  • Respect the same permissions as the client
  • Build user-focused APIs that behave like Appwrite endpoints
  • Process user data without exposing other users' information

Use API Key when your backend needs to:

  • Access all data across all users
  • Perform admin operations
  • Run system-wide queries or reports
  • Bypass user permissions for legitimate reasons

Implementation pattern

Client authenticates

User logs in normally through your app:

const session = await nx.account.createEmailPasswordSession({
    email: 'user@example.com',
    password: 'password'
});

Request JWT token

Generate JWT for server communication:

const jwt = await nx.account.createJWT();

Send to backend

Include JWT in API requests:

const response = await fetch('/api/user-profile', {
    headers: {
        'Authorization': `Bearer ${jwt.jwt}`
    }
});

Server uses JWT

Backend acts with user permissions:

// Extract JWT from request
const userJWT = req.headers.authorization?.replace('Bearer ', '');

// Create client with user permissions
const nx = new Client()
    .setEndpoint('https://api.nuvix.in/v1')
    .setProject('<PROJECT_ID>')
    .setJWT(userJWT);

// Access user data only
const userData = await client.users.get();
const userDocs = await client.schema('db').collection('user-data').find();

Security notes

  • 15-minute expiry - JWT expires automatically for security
  • Session-bound - JWT invalidates when user session ends
  • Permission-restricted - Server can only access what user can access
  • One-time use - Generate new JWT for each server request
  • Secure transmission - Always use HTTPS for JWT exchange

JWT authentication: Your backend becomes an extension of your user, not a backdoor to their data.

How is this guide?

Last updated on

JWT login