2013-08-23 50 views
10

我想用restify.js構建一個REST風格的API,但我不想將API暴露給每個人。我將使用基於令牌的身份驗證。我腦海中的過程就是這樣,我不確定這是否合理。爲restify.js實現基於令牌的身份驗證的最佳方式是什麼?

  1. 用戶向api發送用戶名/密碼來獲取令牌。

  2. 該令牌應該包含在每個其他API的調用請求中。

如果這是合理的,是否有任何node.js庫我可以使用?

另外,如何保護令牌?如果有人用令牌攔截了一個http請求,那麼這個人將獲得api url和令牌。然後他可以根據需要發送請求。有沒有辦法避免這種情況?

非常感謝!

+0

如果你可以使用https,你將不會陷入這樣的中間人攻擊問題。只要你在http上,令牌就會受到攻擊。 – Chandu

+0

謝謝。我聽說使用https將會有一些性能折衷。這是唯一的解決方案嗎?關於我的另一個問題,在node.js中是否有一個用於基於標記的身份驗證的庫?謝謝! – user2440712

+0

http://passportjs.org/它支持oauth – Chandu

回答

24

Basic access authentication

的RESTify捆綁有authorizationParser插件。 authorizationParser解析出Authorization。當插件正在使用時,它將使req.usernamereq.authorization屬性可用。後者的格式是:

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

你的服務器將需要選擇性地截取需要身份驗證請求,並驗證用戶訪問憑據。

下面是一個例子服務器,將需要驗證所有電話:

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

測試的最簡單方法是使用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附帶有支持基本身份驗證內置JsonClient,例如

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

如果你喜歡令牌認證,那麼你可以使用restify-oauth2包實現Client Credentials認證流程,這是你所追求的。

文檔頁面逐步介紹如何設置此類認證,包括每個端點的角色,並且其存儲庫中有一個code example

摘要無論您選擇哪種身份驗證方法的

,所有的人都需要你使用HTTPS。區別在於,如果用戶名/密碼被泄露,用戶需要更改他們的憑據。如果令牌受損,則用戶需要請求新的令牌。後者可以通過編程完成,而前者通常依賴於硬編碼值。

附註。在生產中,如果通過不安全的信道至少傳送一次證書,則證書必須被認爲是「妥協的」,例如,受影響的HTTPS,例如SSL漏洞,例如Heartbleed

+0

作品像一個魅力,謝謝 – Steven

+0

應該更正'req.username'到'req.authorization.basic.username'。 –

+0

如何應用此方法僅驗證某些路線,但允許訪問其他路線? –

相關問題