2013-08-23 5 views
10

Sto cercando di creare un'API RESTful con restify.js, ma non voglio esporre l'API a tutti. E userò l'autenticazione basata su token. Il processo nella mia mente è così, non sono sicuro che sia ragionevole.Qual è il modo migliore per implementare un'autenticazione basata su token per restify.js?

  1. l'utente invia nome utente/password a un API per acquisire il token.

  2. questo token deve essere incluso nella richiesta per le chiamate di ogni altra API.

Se questo è ragionevole, esiste una libreria node.js che posso utilizzare?

Inoltre, come si protegge il token? Se qualcuno intercetta una richiesta http con il token, quella persona otterrà l'api url e il token. Quindi può inviare la richiesta come vuole. c'è un modo per evitarlo?

Grazie mille!

+0

Se è possibile utilizzare https, non si entrerà in tali problemi di attacco da parte di un uomo medio. Finché sarai su http il token sarà compromesso. – Chandu

+0

Grazie. Ho sentito dire che l'uso di https avrà qualche compromesso in termini di prestazioni. È questa l'unica soluzione? E riguardo alla mia altra domanda, esiste una libreria esistente per l'autenticazione basata su token in node.js? Grazie! – user2440712

+0

http://passportjs.org/ ha il supporto per oauth – Chandu

risposta

24

Basic access authentication

Restify è fornito in bundle con una authorizationParser plugin. authorizationParser parser out the Authorization. Quando il plugin è in uso, renderà disponibili le proprietà req.username e req.authorization. Formato di quest'ultimo è:

{ 
    scheme: <Basic|Signature|...>, 
    credentials: <Undecoded value of header>, 
    basic: { 
    username: $user 
    password: $password 
    } 
} 

Il server avrà bisogno di intercettare in modo selettivo le richieste che richiedono l'autenticazione e convalidare le credenziali di accesso degli utenti.

Ecco un server di esempio che richiederà l'autenticazione per tutte le chiamate:

var restify = require('restify'), 
    server; 

server = restify.createServer(); 

server.use(restify.authorizationParser()); 

server.use(function (req, res, next) { 
    var users; 

    // if (/* some condition determining whether the resource requires authentication */) { 
    // return next(); 
    // } 

    users = { 
     foo: { 
      id: 1, 
      password: 'bar' 
     } 
    }; 

    // Ensure that user is not anonymous; and 
    // That user exists; and 
    // That user password matches the record in the database. 
    if (req.username == 'anonymous' || !users[req.username] || req.authorization.basic.password !== users[req.username].password) { 
     // Respond with { code: 'NotAuthorized', message: '' } 
     next(new restify.NotAuthorizedError()); 
    } else { 
     next(); 
    } 

    next(); 
}); 

server.get('/ping', function (req, res, next) { 
    res.send('pong'); 

    next(); 
}); 

server.listen(8080); 

Il modo più semplice per testare sta usando ricciolo:

$ curl -isu foo:bar http://127.0.0.1:8080/ping 

HTTP/1.1 200 OK 
Content-Type: application/json 
Content-Length: 6 
Date: Fri, 12 Dec 2014 10:52:17 GMT 
Connection: keep-alive 

"pong" 

$ curl -isu foo:baz http://127.0.0.1:8080/ping 

HTTP/1.1 403 Forbidden 
Content-Type: application/json 
Content-Length: 37 
Date: Fri, 12 Dec 2014 10:52:31 GMT 
Connection: keep-alive 

{"code":"NotAuthorized","message":""} 

Restify viene fornito con integrato JsonClient che supporta l'autenticazione di base, per esempio

var restify = require('restify'), 
    client; 

client = restify.createJsonClient({ 
    url: 'http://127.0.0.1:8080' 
}); 

client.basicAuth('foo', 'bar'); 

client.get('/ping', function(err, req, res, obj) { 
    console.log(obj); 
}); 

OAuth 2.0

Se si preferisce il token di autenticazione, quindi è possibile utilizzare restify-oauth2 pacchetto che implementa l'autenticazione flusso Client Credentials, che è quello che siete dopo.

La pagina della documentazione descrive passo passo come configurare tale autenticazione, compresi i ruoli di ciascun endpoint, e c'è un code example nel proprio repository.

Sommario

Indipendentemente dal metodo di autenticazione che si sceglie, tutte richiedono l'utilizzo di HTTPS. La differenza è che se il nome utente/password è compromesso, l'utente dovrebbe cambiare le proprie credenziali. Se il token è compromesso, l'utente dovrebbe richiedere un nuovo token. Quest'ultimo può essere fatto a livello di programmazione, mentre il primo di solito si basa su valori hardcoded.

Nota a margine.Nella produzione, le credenziali devono essere considerate "compromesse" se trasferite almeno una volta su un canale non sicuro, ad es. HTTPS compromesso, come nel caso di bug SSL, come ad esempio Heartbleed.

+0

funziona come un incantesimo, grazie – Steven

+0

dovrebbe correggere 'req.username' per' req.authorization.basic.username'. –

+0

Come si applica questo metodo per autenticare solo determinati percorsi ma consentire l'accesso ad altri? –