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.
And use middleware for identifying the user
Is this working already?
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,
From the api key, I added all scope for testing.
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
Oh yes i have two different clients, one for the server and one for the client
Im getting the error (role: users) missing scope (users.write)'
Is it fine if i post screenshots of the code of what my processes were?
Copy and paste would be best
//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);
}
}
i have additional client appwrite service class i wrote, which has all the login, sign up and those methods encapsulated in it.
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
Also, you can't really create a JWT server side without a session already
My account.get() is client side, using appwrite to get current user
with it I have a session already
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;
}
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
And yes i figured it out... thank you
Recommended threads
- self-hosted auth: /v1/account 404 on saf...
Project created in React/Next.js, Appwrite version 1.6.0. Authentication works in all browsers except Safari (ios), where an attempt to connect to {endpoint}/v1...
- Having issues with login via CLI
``` ~/appwrite appwrite login --endpoint https://localhost/v1 --verbose ? Enter your email myvalidemai...
- delete document problems
i don't know what's going on but i get an attribute "tournamentid" not found in the collection when i try to delet the document... but this is just the document...