Back

How to use appwrite sdk with appwrite server sdk via axios

  • 0
  • Self Hosted
  • Accounts
  • Web
  • Users
deeDOF
10 Nov, 2023, 14:28

Please pardon my poor title, I am using NextJs12, I’m working with appwrite client sdk to do a lot of the heavy lifting, but I had a use case where users need to subscribe and then a label is added to them. This label can’t be added via the client sdk, only from the server sdk from my due diligence, I don’t want to use functions, so I chose to add some api, but while designing, I got stuck on how to ensure that only authentication accounts can send requests to that api, and then use that request to identify the user and update the label. And use middleware for identifying the user… but I’ve been searching authentication is done by the client in appwrite if it stores session or cookies, but after sending a test axios request, I saw nothing from appwrite stored.

TL;DR
The user is trying to use the Appwrite SDK with the Appwrite server SDK via axios. They are asking about how the server can use the JWT created by the client to get the user ID. They have shared some code examples of their implementation. Solution: 1. Initialize a separate new client and account instance in the POST function to call `account.get()` and validate the user. 2. Use a client with an API key and the users service to update the user's label. 3. Ensure that the client-side code is creating a JWT using `account.createJWT()` and passing it as a header in the axios
Drake
10 Nov, 2023, 19:25

And use middleware for identifying the user

Is this working already?

deeDOF
10 Nov, 2023, 19:50

No it’s not, I used the method .createJWT from account, and I forwarded what was gotten into the request header, but with in my api route, I used users.client.setjwt().setkey() with the token passed, and api key passed respectively and then tried the users.updateLabels() but I’m getting missing scope account,

deeDOF
10 Nov, 2023, 19:52

From the api key, I added all scope for testing.

Drake
10 Nov, 2023, 20:19

Can you try removing the setKey? It would be best to 2 different clients: one with the jet and the other with the API key

deeDOF
10 Nov, 2023, 20:41

Oh yes i have two different clients, one for the server and one for the client

deeDOF
10 Nov, 2023, 20:56

Im getting the error (role: users) missing scope (users.write)'

deeDOF
10 Nov, 2023, 20:57

Is it fine if i post screenshots of the code of what my processes were?

Drake
10 Nov, 2023, 21:51

Copy and paste would be best

deeDOF
10 Nov, 2023, 22:33
TypeScript

//server-appwrite-config.ts

import { Client } from "node-appwrite";
import conf from "@/conf/config";

const appwriteClient = new Client();

export default appwriteClient
  .setEndpoint(conf.appwriteUrl)
  .setProject(conf.appwriteProjectId)
//.setKey(process.env.APPWRITE_API_SECRET_KEY!);;


//api/users/update-label/route.ts

import { AppwriteException } from "appwrite";
import { NextRequest, NextResponse } from "next/server";
import { Users, Account, Permission } from "node-appwrite";
import appwriteClient from "@/appwrite/server-config";

const users = new Users(appwriteClient);
const account = new Account(appwriteClient);

export async function POST(req: NextRequest) {
  console.log("visiting update label endpoint");
  const reqBody = await req.json();
  const token = reqBody["headers"]["Authorization"].split("Bearer ")[1];
  users.client.setJWT(token);
  users.updateLabels((await account.get()).$id, ["superuser", "superstar"]);
  return NextResponse.json(200);
}

//ProfileCard.tsx
import axios from "axios";

const onSubmit = async () => {
        try {

            const res = await axios.post(`/api/users/update-label`, {
                withCredentials: true,
                headers: {
                    'Authorization': `Bearer ${((await account.createJWT()).jwt)}`,
                    'Content-Type': 'application/json',
                }
            });
            console.log("Successfully submitted", res.data);


        } catch (error: any) {
            console.log("Error: ", error.message);


        }
    }
deeDOF
10 Nov, 2023, 22:36

i have additional client appwrite service class i wrote, which has all the login, sign up and those methods encapsulated in it.

Drake
10 Nov, 2023, 22:43

It looks like you have a single client instance. Can you initialize a separate new client and account instance in the POST function to call account.get() and validate the user? Then, you can use a client with an API key and the users service to update the user's label

Drake
10 Nov, 2023, 22:44

Also, you can't really create a JWT server side without a session already

deeDOF
10 Nov, 2023, 22:50

My account.get() is client side, using appwrite to get current user

deeDOF
10 Nov, 2023, 22:50

with it I have a session already

deeDOF
10 Nov, 2023, 22:52
TypeScript
import conf from "@/conf/config";
import {
  Client,
  Account,
  ID,
  Databases,
  Teams,
  Query,
  QueryTypes,
} from "appwrite";


type CreateUserAccount = {
  email: string;
  password: string;
  name: string;
};

type LoginUserAccount = {
  email: string;
  password: string;
};

const appwriteClient = new Client();

appwriteClient.setEndpoint(conf.appwriteUrl).setProject(conf.appwriteProjectId);

export const account = new Account(appwriteClient);


xport class AppwriteService {
  async createUserAccount({ email, password, name }: CreateUserAccount) {
    try {
      const userAccount = await account.create(
        ID.unique(),
        email,
        password,
        name
      );

      if (userAccount) {
        console.log("Signed up worked");
        return this.login({ email, password });
      } else {
        return userAccount;
      }
    } catch (error) {
      throw error;
    }
  }

  async login({ email, password }: LoginUserAccount) {
    try {
      console.log("logging IN");

      return await account.createEmailSession(email, password);
    } catch (error) {
      console.log("logged error");

      throw error;
    }
  }
  async isLoggedIn(): Promise<boolean> {
    try {
      const data = await this.getCurrentUser();
      return Boolean(data);
    } catch (error) {}
    return false;
  }
  async logout() {
    try {
      return await account.deleteSession("current");
    } catch (error) {
      console.log(error);
      throw error;
    }
  }


 async getCurrentUser() {
    try {
      return await account.get();
    } catch (error) {
      console.log("get current user: " + error);
    }
    return null;
  }
deeDOF
11 Nov, 2023, 09:19

I think Im asking the wrong question, I apologize. How do the server (node-appwrite), use the jwt created by the client (appwrite) to get the user_id

deeDOF
11 Nov, 2023, 09:38

And yes i figured it out... thank you

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