2016-01-14 11 views
14

Facebook non menziona l'autenticazione per la propria libreria GraphQL.Autenticazione e privilegi su Relay/GraphQL

Supponiamo che io abbia una tabella utenti raggiungibile da GraphQL e non desidero divulgare le informazioni degli utenti a nessuno che lo richieda tranne l'utente che ha effettuato l'accesso, a quale livello devo aggiungere il livello di autenticazione?

A livello di schema mutando uno stato "connesso"?

O magari passando parametri aggiuntivi alla funzione graphql che attualmente richiede solo query e schema?

risposta

10

È possibile aggiungere l'intestazione auth con token alle query GraphQL.

var token = localStorage.getItem('id_token'); 

Relay.injectNetworkLayer(
    new Relay.DefaultNetworkLayer('http://pathtohost/graphql', { 
    headers: { 
     Authorization: token 
    } 
    }) 
); 
1

Anche se è davvero poco chiaro nella documentazione, oltre a schema e query (o requestString come viene chiamato nei documenti), è anche possibile passare un rootValue. Tale valore verrà passato a ogni funzione di risoluzione nello schema GraphQL, quindi è dove si desidera inserire qualsiasi informazione di autenticazione abbinata alla richiesta.

Per esempio se si chiama graphql con:

graphql(schema, query, auth, variables) 

nelle funzioni a risolvere avrete accesso a auth:

async user(auth, args) { 
    return await db.users.find(auth, args.id) 
} 
3

Questo post del blog https://medium.com/the-graphqlhub/graphql-and-authentication-b73aed34bbeb#.cpmrcqcyt descrive 3 tipi di autenticazione con il relè.

1 - basato su un token (https://stackoverflow.com/a/34843562/2628278) - Questo bilance meglio \ o/

2 - basato su rootValue (https://stackoverflow.com/a/36001558/2628278)

3 - basata solo in Relay e GraphQL

L' problema con i primi due approcci è che è necessario utilizzare il codice non-relay/graphql per gestirlo.

Il terzo approccio è simile a questo:

{ 
    viewer(token: String) { 
    name 
    } 
} 

passare il token di autenticazione a spettatore, e lasciare graphql gestisce

avrete bisogno di una mutazione così:

mutation { 
    createToken(username: String!, password: String!) { 
    token 
    error 
    } 
} 

che restituirà il token o un errore. Il token deve essere conservato in un biscotto o storage locale sul web e su AsyncStorage su React Native

1

Un'altra opzione è quella di utilizzare una rete Layer Relay diversa da quella di default, come ad esempio nodkz/react-relay-network-layer.

Questo livello di rete supporta il middleware ed è possibile iniettare un authMiddleware per specificare il token di autenticazione per ciascuna richiesta di inoltro. È inoltre possibile specificare cosa fare se il server non riesce a autorizzare la richiesta (ad es.inviare l'utente alla schermata di accesso). Guarda un esempio di come puoi configurarlo:

import { RelayNetworkLayer, urlMiddleware, authMiddleware } from 'react-relay-network-layer'; 

const middlewares = [ 
    urlMiddleware({ 
    url:() => `${graphqlAPIHost}/dragon/v2/graph` 
    }), 
    authMiddleware({ 
    token:() => auth.accessToken(), // Here you retrieve the Auth Access Token 
    tokenRefreshPromise: (req) => { 
     loginActions.logout(); // Here you specify what to do if the server returns 401 
     return req; 
    } 
    }) 
]; 
Relay.injectNetworkLayer(new RelayNetworkLayer(middlewares, { disableBatchQuery: true })); 

In questo modo verrà inviato il token di autenticazione nelle intestazioni della richiesta. Per maggiori informazioni visita la pagina github nodkz/react-relay-network-layer.