2013-08-23 28 views
10

Próbuję zbudować aplikację RESTful z plikiem restify.js, ale nie chcę ujawniać api wszystkim. I będę używać uwierzytelniania opartego na tokenach. Proces w moim umyśle jest taki, nie jestem pewien, czy jest to rozsądne.Jaki jest najlepszy sposób wdrożenia uwierzytelniania opartego na tokenie dla restify.js?

  1. użytkownik wysyła nazwę użytkownika/hasło do api w celu pobrania tokena.

  2. ten token powinien być zawarty we wniosku o połączenie z każdym innym interfejsem API.

Jeśli jest to uzasadnione, czy istnieje biblioteka node.js, której mogę użyć?

Ponadto, w jaki sposób mam chronić token? Jeśli ktoś przechwyci żądanie HTTP z tokenem, to ta osoba otrzyma adres URL i token. Następnie może wysłać żądanie, jak chce. Czy istnieje sposób, aby tego uniknąć?

Wielkie dzięki!

+0

Jeśli możesz użyć protokołu HTTPS, nie dostaniesz się do takich problemów z atakiem pośrednim. Tak długo, jak jesteś na http, token zostanie naruszony. – Chandu

+0

Dziękuję. Słyszałem, że używanie https będzie miało kompromisy w wydajności. Czy to jedyne rozwiązanie? A jeśli chodzi o moje inne pytanie, czy istnieje istniejąca biblioteka do uwierzytelniania opartego na tokenach w pliku node.js? Dzięki! – user2440712

+0

http://passportjs.org/ ma wsparcie dla oauth – Chandu

Odpowiedz

24

Basic access authentication

Restify jest dostarczany z wtyczką authorizationParser. authorizationParser parser out Authorization. Gdy wtyczka jest już używana, udostępni ona właściwości: req.username i req.authorization. Format ten ostatni jest:

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

Twój serwer będzie musiał przechwycić selektywnie wnioski, które wymagają uwierzytelniania i sprawdzania poprawności danych uwierzytelniających dostęp.

Oto serwer przykład, który będzie wymagał uwierzytelniania dla wszystkich połączeń:

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); 

Najprostszym sposobem sprawdzenia używa curl:

$ 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 pochodzi z wbudowanym JsonClient która obsługuje uwierzytelnianie podstawowe, na przykład

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

Jeśli wolisz uwierzytelnianie tokena, a następnie można użyć restify-oauth2 pakiet, który implementuje przepływ uwierzytelniania Client Credentials, który jest to, czego po.

Strona dokumentacji opisuje krok po kroku, jak skonfigurować takie uwierzytelnianie, w tym role każdego punktu końcowego, aw jego repozytorium znajduje się code example.

Podsumowanie

Niezależnie od tego, która metoda uwierzytelniania wybierzesz, wszystkie z nich wymaga użycia protokołu HTTPS. Różnica polega na tym, że jeśli nazwa użytkownika/hasło zostanie naruszone, użytkownik musiałby zmienić swoje poświadczenia. W przypadku złamania tokena użytkownik musiałby poprosić o nowy token. Te ostatnie można wykonać programowo, podczas gdy te pierwsze zwykle opierają się na wartościach zakodowanych na stałe.

Notatka boczna.W produkcji dane uwierzytelniające należy uznać za "zagrożone", jeśli zostały przesłane co najmniej raz przez niezabezpieczony kanał, np. skompromitowany HTTPS, jak w przypadku błędu SSL, takiego jak Heartbleed.

+0

działa jak urok, dzięki – Steven

+0

Powinien poprawić 'req.username' na' req.authorization.basic.username'. –

+0

Jak zastosować tę metodę do uwierzytelniania tylko niektórych tras, ale zezwalać na dostęp innym? –