从属于当前用户的 class 获取对象的最佳方法是什么
What is the best method of getting objects from a class that belong to the current user
我刚开始使用 Parse (REST API),想知道从属于当前用户的 class 获取私有对象的最佳方法。据我所知,有两种选择:
1/ 在查询字符串中传递用户 ID - 我认为这是不好的做法。
2/ 每个对象都会有一个 ACL 集 - 我可以只点击 class 端点并让 ACL 处理事情,而只是 return 属于用户的对象吗?
谢谢。
您可能只让 ACL 使用用户的会话令牌来处理事情。不过,这需要 public 禁用查找访问权限。
它也不理想,因为它不能利用数据库索引。您的数据库将找到与您的查询匹配的所有对象,解析服务器将过滤掉未通过 CLP / ACL 检查的对象。在规模上,这可能会严重损害性能。对象是否只属于一个用户?考虑将用户的 ID 存储在对象上,然后您可以查询与该 ID 匹配的所有对象,并且可以通过该 ID 为您的数据库建立索引以获得快速结果。
Jake 的回答是正确的,但我忍不住用 rest 尝试一下,以防它对任何人有帮助......
const request = require('request-promise');
const baseUrl = 'http://localhost:8378/1'
let sessionToken;
let userId;
let userPointer;
/**
* This test will setup a user, get its sessionToken.
* Create three objects. Two with both a pointer to
* our test user and an acl that only gives our user permission
* to read them. The third test object has no acl so anyone can
* read it.
*
* We then test this setup with two tests:
*
* The first test does a rest query with our test user's
* session token and a where clause to only get our test
* user's objects.
*
* The second test makes an anonymous query to get all
* of the test object. We then verify that we only get
* the one object that is not restricted to our test user.
*/
fdescribe('Get own objects', () => {
beforeEach((done) => {
// create a user to test with
request.post({
uri: `${baseUrl}/users`,
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
},
json: true,
body: {
username: 'tester',
password: 'test'
}
})
.then((r) => {
sessionToken = r.sessionToken;
userId = r.objectId;
userPointer = {
__type: 'Pointer',
className: '_User',
objectId: userId
};
// making the acl in two steps so a prop can
// be set from a variable. The user id was
// returned in the response under 'objectId'
const ACL = {};
ACL[userId] = { read: true, write: true };
return request.post({
uri: `${baseUrl}/batch`,
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
// add our test users sessionToken so the request is
// made with her permissions.
'X-Parse-Session-Token': sessionToken,
},
json: true,
body: {
requests: [
{
method: "POST",
path: "/1/classes/Stuff",
body: {
user: userPointer,
ACL // <-- shorthand notation for ACL: ACL
}
},
{
method: "POST",
path: "/1/classes/Stuff",
body: {
user: userPointer,
ACL
},
},
{
method: "POST",
path: "/1/classes/Stuff",
body: {
// just an empty one so without ACL so we can make sure our where query is working.
}
},
]
}
})
})
.then(done)
.catch(done.fail)
});
it('should be able to fetch our own objects', (done) => {
// make sure our test user can get her own objects
const where = {
user: userPointer
}
request.post({
uri: `${baseUrl}/Classes/Stuff`,
json: {
where,
_method: 'GET'
},
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
'X-Parse-Session-Token': sessionToken,
}
})
.then((response) => expect(response.results.length).toBe(2))
.then(done)
.catch(done.fail);
});
it('should fail to fetch objects that aren\'t ours', (done) => {
// make sure a request not made by our test user doesn't return
// our test user's objects.
request.get({
uri: `${baseUrl}/Classes/Stuff`,
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
},
json: true
})
.then((response) => expect(response.results.length).toBe(1))
.then(done)
.catch(done.fail);
});
});
我刚开始使用 Parse (REST API),想知道从属于当前用户的 class 获取私有对象的最佳方法。据我所知,有两种选择:
1/ 在查询字符串中传递用户 ID - 我认为这是不好的做法。
2/ 每个对象都会有一个 ACL 集 - 我可以只点击 class 端点并让 ACL 处理事情,而只是 return 属于用户的对象吗?
谢谢。
您可能只让 ACL 使用用户的会话令牌来处理事情。不过,这需要 public 禁用查找访问权限。
它也不理想,因为它不能利用数据库索引。您的数据库将找到与您的查询匹配的所有对象,解析服务器将过滤掉未通过 CLP / ACL 检查的对象。在规模上,这可能会严重损害性能。对象是否只属于一个用户?考虑将用户的 ID 存储在对象上,然后您可以查询与该 ID 匹配的所有对象,并且可以通过该 ID 为您的数据库建立索引以获得快速结果。
Jake 的回答是正确的,但我忍不住用 rest 尝试一下,以防它对任何人有帮助......
const request = require('request-promise');
const baseUrl = 'http://localhost:8378/1'
let sessionToken;
let userId;
let userPointer;
/**
* This test will setup a user, get its sessionToken.
* Create three objects. Two with both a pointer to
* our test user and an acl that only gives our user permission
* to read them. The third test object has no acl so anyone can
* read it.
*
* We then test this setup with two tests:
*
* The first test does a rest query with our test user's
* session token and a where clause to only get our test
* user's objects.
*
* The second test makes an anonymous query to get all
* of the test object. We then verify that we only get
* the one object that is not restricted to our test user.
*/
fdescribe('Get own objects', () => {
beforeEach((done) => {
// create a user to test with
request.post({
uri: `${baseUrl}/users`,
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
},
json: true,
body: {
username: 'tester',
password: 'test'
}
})
.then((r) => {
sessionToken = r.sessionToken;
userId = r.objectId;
userPointer = {
__type: 'Pointer',
className: '_User',
objectId: userId
};
// making the acl in two steps so a prop can
// be set from a variable. The user id was
// returned in the response under 'objectId'
const ACL = {};
ACL[userId] = { read: true, write: true };
return request.post({
uri: `${baseUrl}/batch`,
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
// add our test users sessionToken so the request is
// made with her permissions.
'X-Parse-Session-Token': sessionToken,
},
json: true,
body: {
requests: [
{
method: "POST",
path: "/1/classes/Stuff",
body: {
user: userPointer,
ACL // <-- shorthand notation for ACL: ACL
}
},
{
method: "POST",
path: "/1/classes/Stuff",
body: {
user: userPointer,
ACL
},
},
{
method: "POST",
path: "/1/classes/Stuff",
body: {
// just an empty one so without ACL so we can make sure our where query is working.
}
},
]
}
})
})
.then(done)
.catch(done.fail)
});
it('should be able to fetch our own objects', (done) => {
// make sure our test user can get her own objects
const where = {
user: userPointer
}
request.post({
uri: `${baseUrl}/Classes/Stuff`,
json: {
where,
_method: 'GET'
},
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
'X-Parse-Session-Token': sessionToken,
}
})
.then((response) => expect(response.results.length).toBe(2))
.then(done)
.catch(done.fail);
});
it('should fail to fetch objects that aren\'t ours', (done) => {
// make sure a request not made by our test user doesn't return
// our test user's objects.
request.get({
uri: `${baseUrl}/Classes/Stuff`,
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
},
json: true
})
.then((response) => expect(response.results.length).toBe(1))
.then(done)
.catch(done.fail);
});
});