Okay, as I mentioned earlier, I'm using a proxy server. When a user makes a request to the proxy server and they are authenticated with the external auth system, I'll get their Auth token on the request object and verify it on the server. Appwrite allows setting user permissions regardless of whether the role exists or not. For example, I can set a collection permission like this 'write("user:273")'
, and appwrite will allow it even if the user with the id of 273
doesn't actually exist in my appwrite's user base. That's what I'm taking advantage of. So, I can just use any user id from an external auth system in my permission definition for any appwrite resource.
When the user makes the request, I verify their token, and get their id, and then, if the user is trying to access a document for example using the GetDocument
endpoint, I'll fetch the collection, read it's permission field and see if the user's role is included in the read
permissions. If it's there, I proxy the request directly to the user on the client. If not, I check if document security is enabled on the collection, if not, I return a 401, else, I fetch the document and see if it's permissions field includes a read permission for the user. If it does, I return the document, else, I return a 401.
This is just an overview of it, not how I actually plan to implement it.
Btw, I do all the fetches on the proxy server with API key Auth.
Back to the original question I asked though, I think it would be best to place some restrictions when taking my approach. I have defined some and I think they'll work well
Instead of having to carry out crazy relationship parsing and other stuff
Gotcha.
Btw, can you help answer this https://discord.com/channels/564160730845151244/1123702516123705385/1123962148842901607
Btw, I know not all appwrite endpoints need to be proxied, so only the necessary ones will be proxied
An endpoint like the locale get endpoint doesn't need the user to be authenticated via appwrite to function properly, so direct client side access to the locale service won't be blocked
What you can do for this approach is to utilize two features of Appwrite
- Users
- Teams In such way that all the filtering process will be made for you by Appwrite.
Something like this
Create user
For each of your external Auth users create a second user inside Appwrite. Give all users the same default password.
const id = 1; // for example
const defaultPassword = 1234;
const promise = account.create(id, `${id}@example.com`, 'password');
Get the user JWT
To get Appwrite user JWT in a server side can be a bit tricky, so you'll need to use axios
with some cookie jar
and access the Account API by using the Account client REST API
First install this package
https://github.com/3846masa/axios-cookiejar-support#readme
Then you can have an axios clients that holds cookies
import axios from 'axios';
import { wrapper } from 'axios-cookiejar-support';
import { CookieJar } from 'tough-cookie';
const jar = new CookieJar();
const client = wrapper(axios.create({ jar }));
Now you'll need to request two endpoints
- [POST] -
/v1/account/sessions/email
- For creating the session
- [POST] -
/v1/account/jwt
- For getting user JWT.
const endpoint = 'https://cloud.appwrite.io';
const options = {
headers: {
'x-appwrite-project': 'projectID'
}
};
async function getJWTOnServerSide(email, password) {
try {
// Log-in the user.
await client.post(`${endpoint}/v1/account/sessions/email`, {email, password}, options);
const res = await client.post(`${endpoint}/v1/account/jwt`, {} ,options);
return res.data['jwt']
} catch (e) {
return '';
}
}
Execute on behalf of the user
Now that you get the user JWT you can initialize a Server side client with the user JWT like so
const { Client } = require('node-appwrite');
const clientWithUser = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('[PROJECT_ID]')
.setJWT('Current user generated JWT');
Then when you'll use this client to run listDocuments
you'll get only the documents that has permission to read.
const databases = new Databases(clientWithUser);
const promise = databases.listDocuments('[DATABASE_ID]', '[COLLECTION_ID]');
This requires direct client side access to be enabled, right?
Doesn't it?
Yep, but you can block the access to that by blocking the access to your Appwrite server from the outside So the connection is isolated.
I don't get you
Right now can any one expect your system cann acess Appwrite?
If direct client side access is enabled, then any body can actually guess the password I'm using for all users and do the same thing I'm doing on the server directly on the client, isn't that so. I think it is
Maybe, maybe not. But as a security measure, I can't assume that they won't know I'm accessing Appwrite
Is this is not your infrastructure?
Yes, but for it to work, direct client side access must be disabled
And you approach requires direct client side access to be enabled
Why you need it to be disabled? If you're using a Firewall that allow access to Appwrite only to your external server IP, then you can enjoy from both worlds.
By the way, I'm not using self hosted appwrite. I'm using Appwrite cloud
Ohh, then I get the problem of using that approach.
It has to be disabled because if it isn't, users will be able to make direct requests to it.
This is required because I need appwrite to ignore whatever permissions I have defined, especially "user:userID" permissions since the user id is source from an external point. A user could create an appwrite account and get assigned an id that has been assigned to another user in my external system, and this, appwrite will process the user id and let the user that wasn't intended access to eventually get access
Yeah. Exactly...
https://discord.com/channels/564160730845151244/1123704308966379552/1123972307057119273
I still like this approach since you can make use of Appwrite's permission system
Yeah, I really would love to use it too, but I later why it can't be used
Recommended threads
- I recently applied for the free plan und...
I recently applied for the free plan under the GitHub Student Developer Pack. However, my billing status still shows $15, and it mentions that this amount will ...
- Bug Report: Appwrite Console UI Issue on...
Steps to Reproduce: - Navigate to any collection page in the Appwrite console UI. - Open the menu and click on "Create Collection." - Observe that the dialog to...
- Current User is Not authorized
recreating same Thread