Back

Function Secutity: JWT Verification Required or not?

  • 0
  • Functions
xue
31 Oct, 2023, 00:24

Hi guys, i need an idea about it I am creating document with appwrite functions for my project.

Note: I gave Users permission to this spesific function.

When i get POST request from client side, function is triggering and i am checking headers with

TypeScript
throwIfMissing(req.headers, ['x-appwrite-user-id', 'x-appwrite-user-jwt']);

i want to create a document with permissions with the node-appwrite sdk.

But before i start,

My first question is that should i check jwt is valid or not?

TypeScript
  // START: VERIFY USER WITH JWT
  try {
    const verifyUser = new Client()
      .setEndpoint(process.env.APP_ENDPOINT)
      .setProject(process.env.APP_PROJECT)
      .setJWT(req.headers['x-appwrite-user-jwt']);

    const account = new Account(verifyUser);
    const user = await account.get();
    log(`user: ${JSON.stringify(user)}`);

    if (user.$id === req.headers['x-appwrite-user-id']) {
      log('jwt is valid');
    } else {
      log('jwt is invalid');
      return res.json({ ok: false, error: 'jwt is invalid' }, 400);
    }
  } catch (err) {
    log('jwt is invalid');
    return res.json({ ok: false, error: err.message }, 400);
  }
  // END: VERIFY USER WITH JWT

My second question is that 10% of executions are going to end with Timeout What is the possible reasons for that?

I am creating 2 different client with jwt to check sender session is alive or not and the api key to give document based permissions.

TL;DR
The user is questioning whether they should validate the JWT token in their function and what could be causing timeouts in 10% of the executions. Solution: It is unnecessary to check if the JWT is valid as it is generated by Appwrite. As for the timeouts, the user is creating two different clients with JWT and API key. This might be causing the timeouts. They should optimize their code and consider using a single client.
xue
31 Oct, 2023, 00:24

extra: all function code is below im open with optimization suggestions

TypeScript
import { throwIfMissing } from './utils.js';
import {
  Client,
  Databases,
  Account,
  ID,
  Permission,
  Role,
} from 'node-appwrite';

export default async ({ req, res, log, error }) => {
  try {
    log(`req: ${JSON.stringify(req)}`);
    throwIfMissing(req.headers, ['x-appwrite-user-id', 'x-appwrite-user-jwt']);
    const body = JSON.parse(req.bodyRaw);
    throwIfMissing(body, ['to']);
  } catch (err) {
    return res.json({ ok: false, error: err.message }, 400);
  }

  const body = JSON.parse(req.bodyRaw);
  log(`body: ${JSON.stringify(body)}`);

  // TODO: #237 #SECURITY: VERIFY USER WITH JWT
  // START: VERIFY USER WITH JWT
  try {
    const verifyUser = new Client()
      .setEndpoint(process.env.APP_ENDPOINT)
      .setProject(process.env.APP_PROJECT)
      .setJWT(req.headers['x-appwrite-user-jwt']);

    const account = new Account(verifyUser);
    const user = await account.get();
    log(`user: ${JSON.stringify(user)}`);

    if (user.$id === req.headers['x-appwrite-user-id']) {
      log('jwt is valid');
    } else {
      log('jwt is invalid');
      return res.json({ ok: false, error: 'jwt is invalid' }, 400);
    }
  } catch (err) {
    log('jwt is invalid');
    return res.json({ ok: false, error: err.message }, 400);
  }
  // END: VERIFY USER WITH JWT

  const client = new Client()
    .setEndpoint(process.env.APP_ENDPOINT)
    .setProject(process.env.APP_PROJECT)
    .setKey(process.env.API_KEY);

  const database = new Databases(client);

  // Create a room
  let roomData = { users: [req.headers['x-appwrite-user-id'], body.to] };
  let room = await database.createDocument(
    process.env.APP_DATABASE,
    process.env.ROOMS_COLLECTION,
    ID.unique(),
    roomData,
    [
      Permission.read(Role.user(req.headers['x-appwrite-user-id'])),
      Permission.read(Role.user(body.to)),
    ]
  );
  log(room);

  return res.json(room);
};
Drake
31 Oct, 2023, 00:34

My first question is that should i check jwt is valid or not?

No need. This is generated by Appwrite and should be valid.

My second question is that 10% of executions are going to end with Timeout What is the possible reasons for that?

Not sure 😬

xue
31 Oct, 2023, 00:38

thats ok, but someone can change jwt to send POST request to manupulate function , in this way or without jwt, is that any guarantee that function will not be triggered?

because with body data and header, i am creating a document

TypeScript
  // Create a room
  let roomData = { users: [req.headers['x-appwrite-user-id'], body.to] };
  let room = await database.createDocument(
    process.env.APP_DATABASE,
    process.env.ROOMS_COLLECTION,
    ID.unique(),
    roomData,
...
Drake
31 Oct, 2023, 00:40

try it

xue
31 Oct, 2023, 00:46

ok i will try

about 2nd question, all executions completed under 50ms but some of them takes timeout.

every execution i am creating a client like that, is it right usage ? Maybe because of that im getting timeout too much clients..

TypeScript
  const client = new Client()
    .setEndpoint(process.env.APP_ENDPOINT)
    .setProject(process.env.APP_PROJECT)
    .setKey(process.env.API_KEY);

  const database = new Databases(client);
Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more