當(dāng)應(yīng)用程序首次連接到 Moralis 時(shí),它會使用應(yīng)用程序 ID 來標(biāo)識自己。此密鑰作為您的應(yīng)用程序的一部分提供,任何人都可以從他們的設(shè)備反編譯您的應(yīng)用程序或代理網(wǎng)絡(luò)流量以找到它。使用 JavaScript 可以更輕松地利用這一漏洞——只需在瀏覽器中“查看源代碼”并立即找到您的客戶端密鑰。
這就是 Moralis 具有許多其他安全功能來幫助您保護(hù)數(shù)據(jù)的原因。
客戶端密鑰已提供給您的用戶,因此任何僅使用客戶端密鑰即可完成的事情對公眾來說是可行的,甚至是惡意黑客。
另一方面,萬能鑰匙絕對是一種安全機(jī)制。使用主密鑰可以繞過應(yīng)用程序的所有安全機(jī)制,例如類級別權(quán)限和 ACL。擁有主密鑰就像擁有對應(yīng)用程序服務(wù)器的 root 訪問權(quán)限,您應(yīng)該像保護(hù)生產(chǎn)機(jī)器的 root 密碼一樣熱情地保護(hù)您的主密鑰。
總體理念是限制客戶端的權(quán)力(使用客戶端密鑰)并執(zhí)行任何需要 Cloud Code 中的主密鑰的敏感操作。您將在標(biāo)題為“在云代碼中實(shí)現(xiàn)業(yè)務(wù)邏輯”的部分中學(xué)習(xí)如何最好地利用這種能力。
最后說明:建議在您的服務(wù)器中設(shè)置 HTTPS 和 SSL,以避免中間人攻擊,但 Moralis 也適用于非 HTTPS 連接。
第二級安全性是架構(gòu)和數(shù)據(jù)級別。 在此級別執(zhí)行安全措施將限制客戶端應(yīng)用程序訪問和創(chuàng)建 Moralis 數(shù)據(jù)的方式和時(shí)間。 當(dāng)您第一次開始開發(fā) Moralis 應(yīng)用程序時(shí),會設(shè)置所有默認(rèn)值,以便您可以成為更有效率的開發(fā)人員。 例如:
您可以將這些權(quán)限中的任何一個配置為適用于所有人、任何人或應(yīng)用程序中的特定用戶或角色。
角色是包含用戶或其他角色的組,您可以將其分配給對象以限制其使用。 授予角色的任何權(quán)限也授予其任何子項(xiàng),無論他們是用戶還是其他角色,使您能夠?yàn)槟膽?yīng)用程序創(chuàng)建訪問層次結(jié)構(gòu)。
一旦你確信你在你的應(yīng)用程序中擁有正確的類和類之間的關(guān)系,你應(yīng)該開始通過執(zhí)行以下操作來鎖定它:
幾乎您創(chuàng)建的每個類都應(yīng)該在某種程度上調(diào)整這些權(quán)限。 對于每個對象都具有相同權(quán)限的類,類級別的設(shè)置將是最有效的。 例如,一個常見的用例需要擁有一類任何人都可以讀取但沒有人可以寫入的靜態(tài)數(shù)據(jù)。
Moralis 允許您指定每個類允許的操作。 這使您可以限制客戶端訪問或修改您的類的方式。 要更改這些設(shè)置,請轉(zhuǎn)到“數(shù)據(jù)瀏覽器”,選擇一個類,然后單擊“安全”按鈕。
您可以配置客戶端對所選類執(zhí)行以下每個操作的能力:
Get
?:如果用戶知道自己的?objectIds
?,就可以獲取該表中的對象。Find
?:任何擁有 Find 權(quán)限的人都可以查詢表中的所有對象,即使他們不知道自己的 ?objectId
?。除非您在每個對象上放置 ACL,否則任何具有公共 Find 權(quán)限的表都將完全被公眾讀取。objectId
?。對于上述每個操作,您可以向所有用戶授予權(quán)限(這是默認(rèn)設(shè)置),或?qū)?quán)限鎖定到角色和用戶列表。
例如,一個應(yīng)該對所有用戶都可用的類將通過僅啟用 get 和 find 設(shè)置為只讀。 通過只允許創(chuàng)建,可以將日志記錄類設(shè)置為只寫。 您可以通過提供對一組特定用戶或角色的更新和刪除訪問權(quán)限來啟用用戶生成內(nèi)容的審核。
鎖定架構(gòu)和類級別權(quán)限后,就該考慮用戶如何訪問數(shù)據(jù)了。 對象級訪問控制使一個用戶的數(shù)據(jù)與另一個用戶的數(shù)據(jù)分開,因?yàn)橛袝r(shí)一個類中的不同對象需要由不同的人訪問。 例如,用戶的私人個人數(shù)據(jù)應(yīng)該只有他們才能訪問。
對于那些想要存儲和保護(hù)用戶特定數(shù)據(jù)而不需要顯式登錄的應(yīng)用程序,Moralis 還支持匿名用戶的概念。
當(dāng)用戶登錄應(yīng)用程序時(shí),他們會啟動與 Moralis 的會話。 通過此會話,他們可以添加和修改自己的數(shù)據(jù),但無法修改其他用戶的數(shù)據(jù)。
控制誰可以訪問哪些數(shù)據(jù)的最簡單方法是通過訪問控制列表,通常稱為 ACL。 ACL 背后的想法是每個對象都有一個用戶和角色列表以及該用戶或角色擁有的權(quán)限。 用戶需要讀取權(quán)限(或必須屬于具有讀取權(quán)限的角色)才能檢索對象的數(shù)據(jù),并且用戶需要寫入權(quán)限(或必須屬于具有寫入權(quán)限的角色)才能更新或刪除該對象 目的。
擁有用戶后,您就可以開始使用 ACL。 請記住,可以通過傳統(tǒng)的用戶名/密碼注冊、通過 Facebook 或 Twitter 等第三方登錄系統(tǒng),甚至使用 Moralis 的自動匿名用戶功能來創(chuàng)建用戶。 要將當(dāng)前用戶數(shù)據(jù)的 ACL 設(shè)置為不公開可讀,您所要做的就是:
var user = Moralis.User.current();
user.setACL(new Moralis.ACL(user));
大多數(shù)應(yīng)用程序都應(yīng)該這樣做。如果您存儲任何敏感的用戶數(shù)據(jù),例如電子郵件地址或電話號碼,則需要設(shè)置這樣的 ACL,以便其他用戶看不到用戶的私人信息。如果一個對象沒有 ACL,那么每個人都可以讀寫。默認(rèn)情況下,Moralis 在新的用戶對象上設(shè)置 ACL,以便只有用戶可以讀取或?qū)懭胨麄冏约旱臄?shù)據(jù)。 (如果您作為開發(fā)人員需要更新其他 _User 對象,請記住您的主密鑰可以提供執(zhí)行此操作的能力。)
如果您希望用戶擁有一些公開的數(shù)據(jù)和一些私有的數(shù)據(jù),最好有兩個單獨(dú)的對象。您可以從公共數(shù)據(jù)中添加指向私有數(shù)據(jù)的指針。
您還可以為類中的不同列設(shè)置不同的權(quán)限。有關(guān)實(shí)際演示,請參閱視頻。
當(dāng)然,您可以對一個對象設(shè)置不同的讀寫權(quán)限。例如,這是為用戶的公開帖子創(chuàng)建 ACL 的方式,任何人都可以閱讀它:
var acl = new Moralis.ACL();
acl.setPublicReadAccess(true);
acl.setWriteAccess(Moralis.User.current().id, true);
有時(shí)在每個用戶的基礎(chǔ)上管理權(quán)限是不方便的,并且您希望擁有一組獲得相同待遇的用戶(例如一組具有特殊權(quán)力的管理員)。 角色是一種特殊的對象,可讓您創(chuàng)建一組可以全部分配給 ACL 的用戶。 角色的最佳之處在于,您可以在角色中添加和刪除用戶,而無需更新僅限于該角色的每個對象。 要創(chuàng)建只能由管理員寫入的對象:
var acl = new Moralis.ACL();
acl.setPublicReadAccess(true);
acl.setRoleWriteAccess("admins", true);
當(dāng)然,這個片段假設(shè)你已經(jīng)創(chuàng)建了一個名為“admins”的角色。 當(dāng)您在開發(fā)應(yīng)用程序時(shí)設(shè)置了一小組特殊角色時(shí),這通常是合理的。 角色也可以即時(shí)創(chuàng)建和更新——例如,在每次連接后將新朋友添加到“friendOf___”角色。
這一切只是一個開始。 應(yīng)用程序可以通過 ACL 和類級別權(quán)限強(qiáng)制執(zhí)行各種復(fù)雜的訪問模式。 例如:
這是一個 ACL 的格式,它限制所有者(其 objectId 由“?aSaMpLeUsErId
?”標(biāo)識)的讀寫權(quán)限并允許其他用戶讀取該對象:
{
"*": { "read":true },
"aSaMpLeUsErId": { "read" :true, "write": true }
}
這是使用角色的 ACL 格式的另一個示例:
{
"role:RoleName": { "read": true },
"aSaMpLeUsErId": { "read": true, "write": true }
}
指針權(quán)限是一種特殊類型的類級別權(quán)限,它根據(jù)存儲在這些對象的指針字段中的用戶,在類中的每個對象上創(chuàng)建一個虛擬 ACL。例如,給定一個具有 owner 字段的類,在 owner 上設(shè)置讀取指針權(quán)限將使類中的每個對象只能由該對象的 owner 字段中的用戶讀取。對于有發(fā)送者和接收者字段的類,接收者字段的讀指針權(quán)限和發(fā)送者字段的讀寫指針權(quán)限將使類中的每個對象在發(fā)送者和接收者字段中用戶可讀,可寫僅由用戶在發(fā)件人字段中。
鑒于對象通常已經(jīng)具有指向應(yīng)該對對象具有權(quán)限的用戶的指針,指針權(quán)限提供了一種簡單而快速的解決方案,用于使用已經(jīng)存在的數(shù)據(jù)保護(hù)您的應(yīng)用程序,無需編寫任何客戶端代碼或云代碼。
指針權(quán)限類似于虛擬 ACL。它們不會出現(xiàn)在 ACL 列中,但如果您熟悉 ACL 的工作原理,則可以將它們視為 ACL。在上面的發(fā)送方和接收方示例中,每個對象的行為就好像它具有以下 ACL:
{
"<SENDER_USER_ID>": {
"read": true,
"write": true
},
"<RECEIVER_USER_ID>": {
"read": true
}
}
請注意,此 ACL 實(shí)際上并不是在每個對象上創(chuàng)建的。 當(dāng)您添加或刪除指針權(quán)限時(shí),任何現(xiàn)有的 ACL 都不會被修改,并且任何嘗試與對象交互的用戶只有在指針權(quán)限創(chuàng)建的虛擬 ACL 和對象上已經(jīng)存在的真實(shí) ACL 都允許的情況下才能與對象交互 互動。 出于這個原因,將指針權(quán)限和 ACL 結(jié)合起來有時(shí)會讓人感到困惑,因此我們建議對沒有設(shè)置很多 ACL 的類使用指針權(quán)限。 幸運(yùn)的是,如果您以后決定使用云代碼或 ACL 來保護(hù)您的應(yīng)用程序,則很容易刪除指針權(quán)限。
CLP ?requiresAuthentication
?防止任何未經(jīng)身份驗(yàn)證的用戶執(zhí)行受 CLP 保護(hù)的操作。
例如,如果您想允許經(jīng)過身份驗(yàn)證的用戶從您的應(yīng)用程序中查找并獲取公告,并且您的管理員角色擁有所有特權(quán),您可以設(shè)置 CLP:
// POST https://my-moralis-dapp.com/schemas/Announcement
// Note: You need to use PUT http method if the class already exists
// Set the X-Parse-Application-Id and X-Parse-Master-Key header
// body:
{
"classLevelPermissions":
{
"find": {
"requiresAuthentication": true,
"role:admin": true
},
"get": {
"requiresAuthentication": true,
"role:admin": true
},
"create": { "role:admin": true },
"update": { "role:admin": true },
"delete": { "role:admin": true }
}
}
影響:
sessionToken
?的用戶)將能夠讀取該類中的所有對象。警告:請注意,這絕不會保護(hù)您的內(nèi)容,如果您允許任何人登錄到您的服務(wù)器,每個客戶端仍然可以查詢此對象。
類級別權(quán)限 (CLP) 和訪問控制列表 (ACL) 都是保護(hù)您的應(yīng)用程序的強(qiáng)大工具,但它們的交互并不總是與您預(yù)期的完全一致。 它們實(shí)際上代表了兩個獨(dú)立的安全層,每個請求都必須通過這些層才能返回正確的信息或進(jìn)行預(yù)期的更改。 這些層,一個在類級別,一個在對象級別,如下所示。 請求必須通過兩層檢查才能獲得授權(quán)。 請注意,盡管行為類似于 ACL,但指針權(quán)限是一種類級別權(quán)限,因此請求必須通過指針權(quán)限檢查才能通過 CLP 檢查。
如您所見,當(dāng)您同時(shí)使用 CLP 和 ACL 時(shí),用戶是否有權(quán)發(fā)出請求會變得很復(fù)雜。 讓我們看一個示例,以更好地了解 CLP 和 ACL 如何交互。 假設(shè)我們有一個 Photo 類,其中包含一個對象 photoObject。 我們的應(yīng)用中有 2 個用戶,user1 和 user2。 現(xiàn)在假設(shè)我們在 Photo 類上設(shè)置了 Get CLP,禁用公共 Get,但允許 user1 執(zhí)行 Get。 現(xiàn)在讓我們在 photoObject 上設(shè)置一個 ACL 以允許讀取 - 包括 GET - 僅用于 user2。
您可能期望這將允許 user1 和 user2 都獲取 photoObject,但是由于身份驗(yàn)證的 CLP 層和 ACL 層始終有效,因此實(shí)際上它使 user1 和 user2 都無法獲取 photoObject。如果 user1 嘗試獲取 photoObject,它會通過 CLP 層的認(rèn)證,但會因?yàn)闆]有通過 ACL 層而被拒絕。同理,如果 user2 試圖獲取 photoObject,也會在 CLP 認(rèn)證層被拒絕。
現(xiàn)在讓我們看一個使用指針權(quán)限的示例。假設(shè)我們有一個帶有對象 myPost 的 Post 類。我們的應(yīng)用中有兩個用戶,poster 和 viewer。假設(shè)我們添加了指針權(quán)限,允許 Post 類的 Creator 字段中的任何人對該對象進(jìn)行讀寫訪問,而對于 myPost 對象,poster 是該字段中的用戶。對象上還有一個 ACL,為查看器提供讀取訪問權(quán)限。您可能期望這將允許發(fā)布者閱讀和編輯 myPost,并且查看者可以閱讀它,但是查看者將被指針權(quán)限拒絕,并且發(fā)布者將被 ACL 拒絕,所以同樣,兩個用戶都無法訪問目的。
由于 CLP、指針權(quán)限和 ACL 之間的復(fù)雜交互,我們建議在一起使用它們時(shí)要小心。僅使用 CLP 來禁用特定請求類型的所有權(quán)限,然后將指針權(quán)限或 ACL 用于其他請求類型通常很有用。例如,您可能希望為 Photo 類禁用 Delete,但隨后在 Photo 上放置一個指針權(quán)限,以便創(chuàng)建它的用戶可以編輯它,而不是刪除它。由于指針權(quán)限和 ACL 交互的方式特別復(fù)雜,我們通常建議只使用這兩種安全機(jī)制中的一種。
Moralis 中有一些特殊的類不遵循與其他所有類相同的所有安全規(guī)則。 并非所有類都完全遵循類級別權(quán)限 (CLP) 或訪問控制列表 (ACL) 的定義方式,這里記錄了這些例外情況。
這里,“正常行為”是指 CLP 和 ACL 正常工作,而其他特殊行為在腳注中描述。
?_User ? |
?_Installation ? |
|
Get | normal behavior [1, 2, 3] | ignores CLP, but not ACL |
Find | normal behavior [3] | master key only [6] |
Create | normal behavior [4] | ignores CLP |
Update | normal behavior [5] | ignores CLP, but not ACL [7] |
Delete | normal behavior [5] | master key only [7] |
Add Field | normal behavior | normal behavior |
/server/login
? 不尊重用戶類上的 Get CLP。登錄僅基于用戶名和密碼,不能使用 CLP 禁用。
/server/users/me
?,不尊重用戶類上的 Get CLP。
installationId
?作為約束,否則不允許查找沒有主密鑰的請求。對于大多數(shù)應(yīng)用程序,您只需要關(guān)心密鑰、類級權(quán)限和對象級 ACL 即可確保您的應(yīng)用程序和用戶數(shù)據(jù)的安全。但是,有時(shí),您會遇到它們還不夠的邊緣情況。對于其他一切,有 Cloud Code。
Cloud Code 允許您將 JavaScript 上傳到 Moralis 的服務(wù)器,我們將為您運(yùn)行它。與在用戶設(shè)備上運(yùn)行的可能已被篡改的客戶端代碼不同,Cloud Code 保證是您編寫的代碼,因此可以承擔(dān)更多責(zé)任。
Cloud Code 的一個特別常見的用例是防止存儲無效數(shù)據(jù)。對于這種情況,惡意客戶端不能繞過驗(yàn)證邏輯尤為重要。
要創(chuàng)建驗(yàn)證函數(shù),Cloud Code 允許您為您的類實(shí)現(xiàn) beforeSave 觸發(fā)器。每當(dāng)保存對象時(shí)都會運(yùn)行這些觸發(fā)器,并允許您修改對象或完全拒絕保存。例如,這是您創(chuàng)建 Cloud Code beforeSave 觸發(fā)器以確保每個用戶都設(shè)置了電子郵件地址的方式:
Moralis.Cloud.beforeSave('_User', request => {
const user = request.object;
if (!user.get("email")) {
throw "Every user must have an email address.";
}
});
驗(yàn)證可以鎖定您的應(yīng)用程序,以便只接受某些值。 您還可以使用 afterSave 驗(yàn)證來規(guī)范化您的數(shù)據(jù)(例如,以相同的方式格式化所有電話號碼或貨幣)。 您可以保留直接從客戶端應(yīng)用程序訪問 Moralis 數(shù)據(jù)的大部分生產(chǎn)力優(yōu)勢,但您也可以動態(tài)為您的數(shù)據(jù)強(qiáng)制執(zhí)行某些不變量。
需要驗(yàn)證的常見場景包括:
雖然驗(yàn)證在 Cloud Code 中通常很有意義,但某些操作可能特別敏感,應(yīng)盡可能小心謹(jǐn)慎。在這些情況下,您可以完全刪除客戶端的權(quán)限或邏輯,而是將所有此類操作集中到 Cloud Code 函數(shù)中。
當(dāng)調(diào)用云代碼函數(shù)時(shí),它可以使用可選的 {?useMasterKey:true
?} 參數(shù)來獲得修改用戶數(shù)據(jù)的能力。使用主密鑰,您的 Cloud Code 函數(shù)可以覆蓋任何 ACL 并寫入數(shù)據(jù)。這意味著它將繞過您在前面部分中設(shè)置的所有安全機(jī)制。
假設(shè)您希望允許用戶“喜歡”一個 Post 對象,而不給予他們對該對象的完全寫入權(quán)限。您可以通過讓客戶端調(diào)用 Cloud Code 函數(shù)而不是修改 Post 本身來做到這一點(diǎn):
應(yīng)謹(jǐn)慎使用萬能鑰匙。僅在需要安全覆蓋的單個 API 函數(shù)調(diào)用中將 ?useMasterKey
?設(shè)置為 ?true
?:
Moralis.Cloud.define("like", async request => {
var post = new Moralis.Object("Post");
post.id = request.params.postId;
post.increment("likes");
await post.save(null, { useMasterKey: true })
});
Cloud Code 的一個非常常見的用例是向特定用戶發(fā)送推送通知。 一般來說,不能信任客戶端直接發(fā)送推送通知,因?yàn)樗麄兛梢孕薷木瘓?bào)文本,或推送給他們不應(yīng)該發(fā)送的人。 您的應(yīng)用程序設(shè)置將允許您設(shè)置是否啟用“客戶端推送”; 我們建議您確保它已被禁用。 相反,您應(yīng)該編寫 Cloud Code 函數(shù),在發(fā)送推送之前驗(yàn)證要推送和發(fā)送的數(shù)據(jù)。
默認(rèn)情況下,Moralis 允許任何 SDK 用戶通過創(chuàng)建新類和更改現(xiàn)有類的結(jié)構(gòu)來修改數(shù)據(jù)庫。
這在開發(fā)階段非常有用,但在您投入生產(chǎn)時(shí)應(yīng)該關(guān)閉,以保護(hù)您的數(shù)據(jù)庫免受垃圾郵件的影響(以防有人使用 SDK 用新的類填充您的數(shù)據(jù)庫或向現(xiàn)有列添加大量列)。
這可以在服務(wù)器設(shè)置中完成。
Moralis 為您提供了多種方法來保護(hù)應(yīng)用程序中的數(shù)據(jù)。在構(gòu)建應(yīng)用程序并評估要存儲的數(shù)據(jù)類型時(shí),您可以決定選擇哪種實(shí)現(xiàn)方式。
您應(yīng)用程序中的大多數(shù)類都屬于幾個易于保護(hù)的類別之一。對于完全公開的數(shù)據(jù),您可以使用類級別的權(quán)限來鎖定表,使其不受任何人的公開可讀和可寫。對于完全私有的數(shù)據(jù),您可以使用 ACL 來確保只有擁有數(shù)據(jù)的用戶才能讀取它。但有時(shí),您會遇到不想要完全公開或完全私有的數(shù)據(jù)的情況。例如,您可能有一個社交應(yīng)用程序,其中您有一個用戶的數(shù)據(jù),這些數(shù)據(jù)應(yīng)該僅供他們認(rèn)可的朋友閱讀。為此,您需要結(jié)合本指南中討論的技術(shù)來準(zhǔn)確啟用您想要的共享規(guī)則。
我們希望您能使用這些工具盡一切可能保護(hù)您的應(yīng)用數(shù)據(jù)和用戶數(shù)據(jù)的安全。一起,我們可以讓網(wǎng)絡(luò)成為一個更安全的地方。
更多建議: