slogan3

Ontwerp een Geavanceerd GraphQL Schema met Geavanceerde Authorization en Toegangsbeheer

description

Met deze prompt kun je een veilig en flexibel GraphQL schema ontwerpen dat complexe toegangsregels ondersteunt. Het helpt je om toepassingen te bouwen die voldoen aan strenge beveiligingsvereisten en tegelijkertijd schaalbaar en onderhoudbaar blijven. Dit lost problemen op rondom ongeautoriseerde toegang en zorgt voor een robuuste architectuur, beter dan standaard schema ontwerpen zonder toegangscontrole.

prompt

Help me een geavanceerd GraphQL schema te ontwerpen dat complexe authorization en toegangsbeheer ondersteunt. Mijn domein is: <beschrijf je domein of toepassingsgebied>. Ik wil ondersteuning voor: <specificeer gewenste authorization methoden zo ...

try_prompt

generate_helper
disclaimerOnPageApi

ai_answers

provider: openai
model: gpt-4.1-nano
Hier is een voorbeeld van een geavanceerd GraphQL-schema voor het domein Financiële dienstverlening met gevoelige klantgegevens, inclusief rolgebaseerde toegangscontrole en best practices: 1. Schema-definitie met toegangscontrole directives 2. Rollen en authenticatie 3. Implementatie-ideeën en best practices --- **1. Schema-definitie** Gebruik custom directives voor toegangscontrole: ```graphql directive @auth(requires: Role = USER) on FIELD_DEFINITION | OBJECT enum Role { ADMIN USER GUEST } type Klant @auth(requires: USER) { id: ID! naam: String! @auth(requires: USER) geboortedatum: String! @auth(requires: USER) saldo: Float! @auth(requires: ADMIN) transacties: [Transactie!]! @auth(requires: USER) } type Transactie { id: ID! datum: String! bedrag: Float! description: String } type Query { klant(id: ID!): Klant @auth(requires: USER) alleKlanten: [Klant!]! @auth(requires: ADMIN) } ``` **2. Implementatie van toegangscontrole** - Voeg een middleware of resolver-wrapper toe die de `@auth` directive leest en controleert of de huidige gebruiker de juiste rol heeft. - Bijvoorbeeld, in Apollo Server kan je een schema-directive maken: ```js class AuthDirective extends SchemaDirectiveVisitor { visitFieldDefinition(field) { const { requires } = this.args; const { resolve = defaultFieldResolver } = field; field.resolve = async function (...args) { const context = args[2]; if (!context.user || !context.user.roles.includes(requires)) { throw new Error('Toegang geweigerd'); } return resolve.apply(this, args); }; } } ``` **3. Authenticatie en rolbeheer** - Beheer gebruikersrollen via een beveiligd identity management systeem. - Gebruik JWT tokens met claims over rollen. - Bij elke request wordt het token geverifieerd en de gebruiker geïdentificeerd. **4. Best practices en schaalbaarheid** - **Fine-grained toegangscontrole:** Gebruik directives voor verschillende velden en objecten, zodat je complexe regels kunt implementeren. - **Centraliseer autorisatie logic:** Plaats alle autorisaties in middleware of directives, niet in de resolvers zelf. - **Caching:** Wees voorzichtig met caching, omdat toegangscontrole dynamisch kan zijn. Gebruik eventueel gescheiden cache-lagen per rol. - **Audit logs:** Log alle toegangsverzoeken en -fouten voor compliance. - **Schema evolutie:** Ontwerp het schema flexibel zodat nieuwe rollen of regels eenvoudig kunnen worden toegevoegd. --- **Kort samengevat:** - Gebruik schema directives voor toegangscontrole. - Beheer rollen en authenticatie via een secure identity provider. - Controleer rollen in middleware/directives. - Pas best practices toe voor schaalbaarheid en beveiliging. Heeft u specifieke onderdelen of voorbeelden nodig?
provider: deepseek
model: deepseek-chat
Zeker, hieronder vindt u een geavanceerd GraphQL schema-ontwerp voor financiële dienstverlening met robuust autorisatiebeheer. --- ### **GraphQL Schema Definitie** ```graphql # Basistypes en authenticatie scalar DateTime scalar EmailAddress scalar IBAN type Mutation { login(email: EmailAddress!, wachtwoord: String!): AuthPayload! refreshToken: AuthPayload! logout: Boolean! } type AuthPayload { token: String! vervaltOp: DateTime! gebruiker: Gebruiker! } # Gebruikersmanagement type Gebruiker { id: ID! email: EmailAddress! rol: GebruikersRol! profiel: GebruikersProfiel! laatsteLogin: DateTime gemaakteRekeningen: [Rekening!]! } type GebruikersProfiel { voornaam: String! achternaam: String! telefoon: String } enum GebruikersRol { ADMIN FINANCEEL_BEHEERDER KLANTENSERVICE GEBRUIKER AUDITOR } # Financiële gegevens type Rekening { id: ID! iban: IBAN! saldo: Float! valuta: Valuta! eigenaar: Gebruiker! transacties( vanaf: DateTime tot: DateTime eerste: Int na: String ): TransactieVerbinding! gevoelig: GevoeligeRekeningGegevens! @auth(requires: [ADMIN, FINANCEEL_BEHEERDER]) } type GevoeligeRekeningGegevens { kredietlimiet: Float! rentepercentage: Float! producttype: RekeningType! } enum RekeningType { ZAKELIJK PARTICULIER SPAAR BELEGGING } enum Valuta { EUR USD GBP } type Transactie { id: ID! bedrag: Float! valuta: Valuta! tegenpartij: Tegenpartij! omschrijving: String! datum: DateTime! categorie: TransactieCategorie! } type Tegenpartij { naam: String! iban: IBAN! } enum TransactieCategorie { INKOMST UITGAVE OVERBOEKING INCASSO } type TransactieVerbinding { paginaInfo: PaginaInfo! edges: [TransactieEdge!]! } type TransactieEdge { node: Transactie! cursor: String! } type PaginaInfo { heeftVolgendePagina: Boolean! endCursor: String } # Query definitie met autorisatie type Query { # Algemene queries mij: Gebruiker! @auth rekeningen: [Rekening!]! @auth # Beheerder-queries alleGebruikers: [Gebruiker!]! @auth(requires: [ADMIN, AUDITOR]) rekeningDetails(id: ID!): Rekening! @auth transactieRapport( rekeningId: ID! vanaf: DateTime! tot: DateTime! ): [Transactie!]! @auth(requires: [ADMIN, FINANCEEL_BEHEERDER]) } # Directives voor autorisatie directive @auth( requires: [GebruikersRol!] = [GEBRUIKER] ) on FIELD_DEFINITION ``` --- ### **Implementatie Best Practices** #### 1. **Autorisatie Laag** ```javascript // authorisation.js class Authorisation { static heeftToegang(context, benodigdeRollen) { const { gebruiker } = context; if (!gebruiker) throw new Error('Niet geauthenticeerd'); if (benodigdeRollen.includes(gebruiker.rol)) return true; // Hiërarchische rechten controle const rechtenHiërarchie = { ADMIN: ['ADMIN', 'FINANCEEL_BEHEERDER', 'KLANTENSERVICE', 'AUDITOR', 'GEBRUIKER'], FINANCEEL_BEHEERDER: ['FINANCEEL_BEHEERDER', 'GEBRUIKER'], KLANTENSERVICE: ['KLANTENSERVICE', 'GEBRUIKER'], AUDITOR: ['AUDITOR'], GEBRUIKER: ['GEBRUIKER'] }; return rechtenHiërarchie[gebruiker.rol]?.some(rol => benodigdeRollen.includes(rol) ) || false; } } ``` #### 2. **Field-level Autorisation Middleware** ```javascript // schema.js const { mapSchema, getDirective, MapperKind } = require('@graphql-tools/utils'); function authDirectiveTransformer(schema) { return mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig) => { const authDirective = getDirective(schema, fieldConfig, 'auth'); if (!authDirective) return fieldConfig; const { requires } = authDirective[0]; const originalResolver = fieldConfig.resolve; fieldConfig.resolve = async (source, args, context, info) => { if (!Authorisation.heeftToegang(context, requires)) { throw new Error('Onvoldoende rechten'); } // Data filtering op resultaatniveau const result = await originalResolver(source, args, context, info); return filterGevoeligeGegevens(result, context.gebruiker.rol); }; return fieldConfig; } }); } function filterGevoeligeGegevens(data, rol) { if (rol !== 'ADMIN' && data?.gevoelig) { const { gevoelig, ...rest } = data; return rest; } return data; } ``` #### 3. **Context Initialisatie** ```javascript // context.js async function createContext({ req }) { const token = req.headers.authorization?.replace('Bearer ', ''); if (!token) return { gebruiker: null }; try { const decoded = verifyJWT(token); const gebruiker = await GebruikerService.vindBijId(decoded.userId); return { gebruiker, rol: gebruiker.rol, permissions: await haalPermissionsOp(gebruiker.rol) }; } catch (error) { throw new AuthenticationError('Ongeldig token'); } } ``` --- ### **Schaalbaarheidsstrategieën** #### 1. **Distributed Caching** ```javascript // cached-resolvers.js const redis = new Redis(process.env.REDIS_URL); const rekeningenResolver = async (parent, args, context) => { const cacheKey = `rekeningen:${context.gebruiker.id}`; const cached = await redis.get(cacheKey); if (cached) return JSON.parse(cached); const result = await RekeningService.vindVoorGebruiker(context.gebruiker.id); await redis.setex(cacheKey, 300, JSON.stringify(result)); // 5 min cache return result; }; ``` #### 2. **DataLoader Pattern** ```javascript // dataloaders.js const gebruikerLoader = new DataLoader(async (ids) => { const gebruikers = await GebruikerService.vindBijIds(ids); return ids.map(id => gebruikers.find(u => u.id === id)); }); const rekeningLoader = new DataLoader(async (gebruikerIds) => { return Promise.all( gebruikerIds.map(id => RekeningService.vindVoorGebruiker(id)) ); }); ``` #### 3. **Query Complexity Limiet** ```javascript // complexity.js const complexityLimit = { maximumComplexity: 1000, onComplete: (complexity) => { if (complexity > 1000) { throw new Error('Query te complex'); } } }; ``` --- ### **Beveiligingsmaatregelen** 1. **JWT Tokens** met korte expiry times (15-30 minuten) 2. **Refresh tokens** met strict server-side storage 3. **Rate limiting** per gebruiker en IP 4. **Query depth limiting** (max 10 levels) 5. **Input validation** met custom scalars 6. **Audit logging** van alle gevoelige operaties 7. **Encryptie** van gevoelige data at rest en in transit --- ### **Monitoring en Logging** ```javascript // audit-logger.js class AuditLogger { static logToegang(gebruiker, operatie, metadata = {}) { logger.info({ type: 'TOEGANGS_CONTROLE', timestamp: new Date().toISOString(), gebruikerId: gebruiker.id, operatie, metadata }); } } // Gebruik in resolvers AuditLogger.logToegang(context.gebruiker, 'REKENING_BEKIJKEN', { rekeningId: args.id, succesvol: true }); ``` Dit schema biedt een schaalbare, veilige basis voor financiële toepassingen met gedetailleerd toegangsbeheer op veld- en operationeel niveau.
error: Generation failed [deepseek] prompt_id=2985 locale=de err=DeepSeek connection/timeout | Generation failed [deepseek] prompt_id=2985 locale=fr err=DeepSeek connection/timeout