sql >> Databasteknik >  >> RDS >> Mysql

Databasschema för ACL

Enligt min erfarenhet är den verkliga frågan mest om huruvida någon användarspecifik åtkomstbegränsning kommer att inträffa eller inte.

Anta till exempel att du designar schemat för en gemenskap och att du tillåter användare att växla synligheten för sin profil.

Ett alternativ är att hålla sig till en offentlig/privat profilflagga och hålla sig till breda, förebyggande behörighetskontroller:'users.view' (visar offentliga användare) kontra säg 'users.view_all' (visar alla användare, för moderatorer) .

En annan innebär mer förfinade behörigheter, du kanske vill att de ska kunna konfigurera saker så att de kan göra sig själva (a) synliga för alla, (b) synliga av sina handplockade kompisar, (c) hållas helt privata och kanske (d) ) kan ses av alla utom deras handplockade bozos. I det här fallet måste du lagra ägar-/åtkomstrelaterad data för enskilda rader, och du måste abstrahera några av dessa saker kraftigt för att undvika att den transitiva stängningen av en tät, orienterad graf uppstår.

Med båda tillvägagångssätten har jag funnit att ökad komplexitet i rollredigering/tilldelning uppvägs av den resulterande lättheten/flexibiliteten vid tilldelning behörigheter till enskilda data, och att följande fungerade bäst:

  1. Användare kan ha flera roller
  2. Roller och behörigheter slås samman i samma tabell med en flagga för att skilja de två åt (användbart när du redigerar roller/tillstånd)
  3. Roller kan tilldela andra roller, och roller och behörigheter kan tilldela behörigheter (men behörigheter kan inte tilldela roller), från samma tabell.

Den resulterande orienterade grafen kan sedan dras i två frågor, byggas en gång för alla inom rimlig tid med vilket språk du än använder, och cachelagras i Memcache eller liknande för efterföljande användning.

Därifrån är det att dra en användares behörigheter en fråga om att kontrollera vilka roller han har, och bearbeta dem med hjälp av behörighetsdiagrammet för att få de slutgiltiga behörigheterna. Kontrollera behörigheter genom att verifiera att en användare har den angivna rollen/behörigheten eller inte. Och kör sedan din fråga/fråga ett fel baserat på den behörighetskontrollen.

Du kan utöka kontrollen för enskilda noder (dvs. check_perms($user, 'users.edit', $node) för "kan redigera denna nod" kontra check_perms($user, 'users.edit') för "kan redigera en nod") om du behöver, och du kommer att ha något mycket flexibelt/lätt att använda för slutanvändare.

Som det inledande exemplet borde illustrera, var försiktig med att styra för mycket mot behörigheter på radnivå. Prestandaflaskhalsen är mindre i att kontrollera en enskild nods behörigheter än i att dra en lista med giltiga noder (dvs. endast de som användaren kan se eller redigera). Jag skulle avråda från allt utöver flaggor och user_id-fält inom själva raderna om du inte är (mycket) väl insatt i frågeoptimering.



  1. DATEADD motsvarighet i PostgreSQL

  2. Hur INTERSECT fungerar i SQL Server

  3. Enhetstestning för PL/SQL

  4. Jag kan inte logga in på min lokala kopia av Magento -- hur använder jag förlorat lösenord med lokal kopia av programvara?