2013-08-23 37 views
10

Tôi đang cố gắng xây dựng một api RESTful với restify.js, nhưng tôi không muốn để lộ api cho tất cả mọi người. Và tôi sẽ sử dụng xác thực dựa trên mã thông báo. Quá trình trong đầu tôi như thế này, tôi không chắc liệu nó có hợp lý hay không.Cách tốt nhất để triển khai xác thực dựa trên mã thông báo cho restify.js là gì?

  1. người dùng gửi tên người dùng/mật khẩu tới api để nhận mã thông báo.

  2. mã thông báo này phải được bao gồm trong yêu cầu cho các cuộc gọi của mọi api khác.

Nếu điều này là hợp lý, có thư viện node.js nào tôi có thể sử dụng không?

Ngoài ra, làm cách nào để bảo vệ mã thông báo? Nếu ai đó chặn yêu cầu http bằng mã thông báo, thì người đó sẽ nhận được url api và mã thông báo. Sau đó, anh ta có thể gửi yêu cầu theo ý muốn. Có cách nào để tránh điều này không?

Cảm ơn rất nhiều!

+0

Nếu bạn có thể sử dụng https, bạn sẽ không gặp phải vấn đề tấn công trung gian như vậy. Miễn là bạn đang sử dụng http thì mã thông báo sẽ bị xâm phạm. – Chandu

+0

Cảm ơn bạn. Tôi đã nghe nói rằng việc sử dụng https sẽ có một số sự cân bằng hiệu suất. Đây có phải là giải pháp duy nhất không? Và liên quan đến câu hỏi khác của tôi, có thư viện hiện có cho xác thực dựa trên mã thông báo trong node.js không? Cảm ơn! – user2440712

+0

http://passportjs.org/ nó có hỗ trợ cho oauth – Chandu

Trả lời

24

Basic access authentication

Restify được đi kèm với một plugin authorizationParser. authorizationParser phân tích cú pháp trong số Authorization. Khi plugin được sử dụng, plugin sẽ tạo các thuộc tính req.usernamereq.authorization. Định dạng sau là:

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

Máy chủ của bạn sẽ cần phải chọn lọc chặn các yêu cầu xác thực và xác thực quyền truy cập của người dùng.

Dưới đây là một máy chủ ví dụ mà sẽ yêu cầu xác thực cho tất cả các cuộc gọi:

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

Cách dễ nhất để kiểm tra được sử dụng 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 đi kèm với inbuilt JsonClient hỗ trợ xác thực cơ bản, ví dụ

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

Nếu bạn thích xác thực thẻ, sau đó bạn có thể sử dụng restify-oauth2 gói mà thực hiện dòng chảy Client Credentials xác thực, đó là những gì bạn đang sau.

Trang tài liệu mô tả từng bước cách thiết lập xác thực như vậy, bao gồm vai trò của mỗi điểm cuối và có code example trong kho lưu trữ của họ.

Tóm tắt

Bất kể phương pháp xác thực mà bạn chọn, tất cả trong số họ yêu cầu bạn phải sử dụng HTTPS. Sự khác biệt là nếu tên người dùng/mật khẩu bị xâm nhập, người dùng sẽ cần thay đổi thông tin đăng nhập của họ. Nếu mã thông báo bị xâm phạm, thì người dùng sẽ cần yêu cầu mã thông báo mới. Sau này có thể được thực hiện theo chương trình, trong khi trước đây thường dựa trên các giá trị hardcoded.

Lưu ý phụ.Trong quá trình sản xuất, thông tin đăng nhập phải được coi là "bị xâm phạm" nếu được chuyển ít nhất một lần qua kênh không an toàn, ví dụ: HTTPS bị xâm phạm, như trong trường hợp lỗi SSL, chẳng hạn như Heartbleed.

+0

hoạt động như một nét duyên dáng, cảm ơn – Steven

+0

Nên sửa 'req.username' thành' req.authorization.basic.username'. –

+0

Làm cách nào để áp dụng phương pháp này để chỉ xác thực các tuyến đường nhất định nhưng cho phép truy cập vào các tuyến khác? –

Các vấn đề liên quan