Làm cách nào để sử dụng API REST trong JavaScript?

Theo mô hình, API REST rất hữu ích và phổ biến đến mức mọi nhà phát triển web, bất kể ngôn ngữ hay nền tảng, đều nên biết cách xây dựng chúng. Trong bài viết này, Nhà phát triển JavaScript Toptal Marcos Henrique da Silva trình bày cách tạo API REST đơn giản và an toàn để quản lý người dùng trên Node. js

Qua

Marcos Henrique da Silva

Marcos có hơn 15 năm kinh nghiệm trong lĩnh vực CNTT và phát triển. Niềm đam mê của anh ấy bao gồm kiến ​​trúc REST, phương pháp phát triển Agile và JavaScript

CHIA SẺ

CHIA SẺ

Ghi chú của biên tập viên. Bài viết này đã được cập nhật vào ngày 2 tháng 12 năm 2022 bởi nhóm biên tập của chúng tôi. Nó đã được sửa đổi để bao gồm các nguồn gần đây và phù hợp với các tiêu chuẩn biên tập hiện tại của chúng tôi

Giao diện lập trình ứng dụng (API) ở khắp mọi nơi. Chúng cho phép phần mềm giao tiếp với các phần mềm khác—nội bộ hoặc bên ngoài—một cách nhất quán, đây là thành phần quan trọng trong khả năng mở rộng, chưa kể đến khả năng sử dụng lại

Ngày nay, các dịch vụ trực tuyến có API công khai khá phổ biến. Điều này cho phép các nhà phát triển khác dễ dàng tích hợp các tính năng như đăng nhập mạng xã hội, thanh toán bằng thẻ tín dụng và theo dõi hành vi. Tiêu chuẩn thực tế mà họ sử dụng cho việc này được gọi là chuyển giao trạng thái đại diện (REST)

Và tại sao lại xây dựng một Node. js REST API, cụ thể là? . NET Core, Laravel (PHP) hoặc Chai (Python) —JavaScript vẫn là một trong số các nhà phát triển chuyên nghiệp. Vì vậy, trong hướng dẫn này, back end API REST cơ bản nhưng an toàn của chúng tôi sẽ tập trung vào các thành phần phổ biến giữa các nhà phát triển JavaScript

  • Nút. js, mà người đọc đã có một số quen thuộc với
  • Thể hiện. js, giúp đơn giản hóa rất nhiều việc xây dựng các tác vụ máy chủ web phổ biến và là giá vé tiêu chuẩn trong việc xây dựng một Nút. js REST kết thúc API
  • Mongoose, sẽ kết nối mặt sau của chúng tôi với cơ sở dữ liệu MongoDB

Các nhà phát triển theo hướng dẫn này cũng sẽ cảm thấy thoải mái với thiết bị đầu cuối (hoặc dấu nhắc lệnh)

Ghi chú. Chúng tôi sẽ không đề cập đến cơ sở mã mặt trước ở đây, nhưng thực tế là mặt sau của chúng tôi được viết bằng JavaScript giúp chia sẻ mã thuận tiện—chẳng hạn như các mô hình đối tượng—trong toàn bộ ngăn xếp

Cấu trúc của API REST

API REST được sử dụng để truy cập và thao tác dữ liệu bằng cách sử dụng một tập hợp các hoạt động phi trạng thái phổ biến. Các hoạt động này là không thể thiếu đối với giao thức HTTP và đại diện cho chức năng tạo, đọc, cập nhật và xóa (CRUD) thiết yếu, mặc dù không phải theo cách trực tiếp rõ ràng

  • app.post('/users', [
       UsersController.insert
    ]);
    
    7 (tạo tài nguyên hoặc thường cung cấp dữ liệu)
  • app.post('/users', [
       UsersController.insert
    ]);
    
    8 (truy xuất chỉ mục tài nguyên hoặc tài nguyên riêng lẻ)
  • app.post('/users', [
       UsersController.insert
    ]);
    
    9 (tạo hoặc thay thế tài nguyên)
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    0 (cập nhật/sửa đổi tài nguyên)
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    1 (xóa tài nguyên)

Sử dụng các thao tác HTTP này và tên tài nguyên làm địa chỉ, chúng ta có thể xây dựng một Nút. js REST API bằng cách tạo một điểm cuối cho mỗi thao tác. Và bằng cách triển khai mẫu, chúng tôi sẽ có một nền tảng ổn định và dễ hiểu cho phép chúng tôi phát triển mã nhanh chóng và duy trì mã sau đó. Nền tảng tương tự sẽ được sử dụng để tích hợp các tính năng của bên thứ ba, hầu hết trong số đó cũng sử dụng API REST, giúp việc tích hợp đó nhanh hơn

Hiện tại, hãy bắt đầu tạo Node an toàn của chúng tôi. API REST của js

Trong hướng dẫn này, chúng ta sẽ tạo một API REST an toàn khá phổ biến (và rất thiết thực) cho một tài nguyên có tên là

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
2

Tài nguyên của chúng tôi sẽ có cấu trúc cơ bản sau

  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    3 (UUID được tạo tự động)
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    4
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    5
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    6
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    7
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    8 (người dùng này được phép làm gì?)

Và chúng ta sẽ tạo các thao tác sau cho tài nguyên đó

  • app.post('/users', [
       UsersController.insert
    ]);
    
    7 trên điểm cuối
    app.post('/users', [
       UsersController.insert
    ]);
    
    30 (tạo người dùng mới)
  • app.post('/users', [
       UsersController.insert
    ]);
    
    8 trên điểm cuối
    app.post('/users', [
       UsersController.insert
    ]);
    
    30 (liệt kê tất cả người dùng)
  • app.post('/users', [
       UsersController.insert
    ]);
    
    8 trên điểm cuối
    app.post('/users', [
       UsersController.insert
    ]);
    
    34 (lấy một người dùng cụ thể)
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    0 trên điểm cuối
    app.post('/users', [
       UsersController.insert
    ]);
    
    34 (cập nhật dữ liệu cho một người dùng cụ thể)
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    1 trên điểm cuối
    app.post('/users', [
       UsersController.insert
    ]);
    
    34 (xóa một người dùng cụ thể)

Chúng tôi cũng sẽ sử dụng mã thông báo web JSON (JWT) cho mã thông báo truy cập. Cuối cùng, chúng tôi sẽ tạo một tài nguyên khác có tên là

app.post('/users', [
   UsersController.insert
]);
39 sẽ yêu cầu email và mật khẩu của người dùng và đổi lại, sẽ tạo mã thông báo được sử dụng để xác thực trong một số hoạt động nhất định. (Bài viết tuyệt vời của Dejan Milosevic về JWT dành cho các ứng dụng REST an toàn trong Java đi sâu vào chi tiết hơn về vấn đề này; các nguyên tắc đều giống nhau. )

Nút. js REST Hướng dẫn thiết lập API

Trước tiên, hãy đảm bảo rằng bạn có phiên bản Node mới nhất. phiên bản js được cài đặt. Đối với bài viết này, tôi sẽ sử dụng phiên bản 14. 9. 0;

Tiếp theo, đảm bảo rằng bạn đã cài đặt MongoDB. Chúng tôi sẽ không giải thích các chi tiết cụ thể của Mongoose và MongoDB được sử dụng ở đây, nhưng để chạy những điều cơ bản, chỉ cần khởi động máy chủ ở chế độ tương tác (i. e. , từ dòng lệnh dưới dạng

app.post('/users', [
   UsersController.insert
]);
30) chứ không phải dưới dạng dịch vụ. Đó là bởi vì, tại một thời điểm trong hướng dẫn này, chúng ta sẽ cần tương tác trực tiếp với MongoDB thay vì thông qua Nút của chúng ta. mã js

Ghi chú. Với MongoDB, không cần phải tạo một cơ sở dữ liệu cụ thể như có thể có trong một số tình huống RDBMS. Cuộc gọi chèn đầu tiên từ Nút của chúng tôi. mã js sẽ tự động kích hoạt quá trình tạo của nó

Hướng dẫn này không chứa tất cả mã cần thiết cho một dự án đang hoạt động. Thay vào đó, dự định là bạn sao chép repo đồng hành và chỉ cần theo dõi những điểm nổi bật khi bạn đọc qua. Nhưng bạn cũng có thể sao chép các tệp và đoạn trích cụ thể từ kho lưu trữ nếu cần, nếu muốn

Điều hướng đến thư mục

app.post('/users', [
   UsersController.insert
]);
31 kết quả trong thiết bị đầu cuối của bạn. Bạn sẽ thấy rằng dự án của chúng tôi chứa ba thư mục mô-đun

  • app.post('/users', [
       UsersController.insert
    ]);
    
    32 (xử lý tất cả các dịch vụ được chia sẻ và thông tin được chia sẻ giữa các mô-đun người dùng)
  • exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    2 (mọi thứ liên quan đến người dùng)
  • app.post('/users', [
       UsersController.insert
    ]);
    
    39 (xử lý việc tạo JWT và luồng đăng nhập)

Bây giờ, hãy chạy

app.post('/users', [
   UsersController.insert
]);
35 (hoặc
app.post('/users', [
   UsersController.insert
]);
36 nếu bạn có)

Xin chúc mừng. Bây giờ bạn có tất cả các phụ thuộc và thiết lập cần thiết để chạy Node đơn giản của chúng tôi. js REST kết thúc API

Tạo mô-đun người dùng

Chúng tôi sẽ sử dụng Mongoose, thư viện mô hình hóa dữ liệu đối tượng (ODM) cho MongoDB, để tạo mô hình người dùng trong lược đồ người dùng

Trước tiên, chúng ta cần tạo lược đồ Mongoose trong

app.post('/users', [
   UsersController.insert
]);
37

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
1

Khi chúng tôi xác định lược đồ, chúng tôi có thể dễ dàng đính kèm lược đồ vào mô hình người dùng

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
2

Sau đó, chúng tôi có thể sử dụng mô hình này để triển khai tất cả các hoạt động CRUD mà chúng tôi muốn trong Express của mình. điểm cuối js

Hãy bắt đầu với thao tác “tạo người dùng” bằng cách xác định Express. tuyến đường js trong

app.post('/users', [
   UsersController.insert
]);
38

app.post('/users', [
   UsersController.insert
]);

Điều này được kéo vào Express của chúng tôi. js trong tệp chính

app.post('/users', [
   UsersController.insert
]);
39. Đối tượng
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
60 được nhập từ bộ điều khiển của chúng tôi, nơi chúng tôi băm mật khẩu một cách thích hợp, được xác định trong
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
61

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};

Tại thời điểm này, chúng ta có thể kiểm tra mô hình Mongoose của mình bằng cách chạy Node. máy chủ API js (

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
62) và gửi yêu cầu
app.post('/users', [
   UsersController.insert
]);
7 tới
app.post('/users', [
   UsersController.insert
]);
30 với một số dữ liệu JSON

app.post('/users', [
   UsersController.insert
]);
3

Có một số công cụ bạn có thể sử dụng cho việc này. Chúng tôi đề cập đến chứng mất ngủ bên dưới, nhưng bạn cũng có thể sử dụng Postman hoặc các giải pháp thay thế mã nguồn mở như cURL (công cụ dòng lệnh) hoặc Bruno. Bạn thậm chí có thể chỉ sử dụng JavaScript—ví dụ: từ bảng điều khiển công cụ phát triển tích hợp trong trình duyệt của bạn—như vậy

app.post('/users', [
   UsersController.insert
]);
3

Tại thời điểm này, kết quả của một bài đăng hợp lệ sẽ chỉ là ID từ người dùng đã tạo.

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
65. Chúng ta cũng cần thêm phương thức
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
66 vào mô hình trong
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
67

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
6

Bây giờ chúng ta cần xem người dùng có tồn tại không. Vì vậy, chúng tôi sẽ triển khai tính năng “nhận người dùng theo id” cho điểm cuối

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
68

Đầu tiên, chúng tôi tạo một Express. tuyến đường js trong

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
69

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
0

Sau đó, chúng tôi tạo bộ điều khiển trong

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
61

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
2

Và cuối cùng, thêm phương thức

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
01 vào mô hình trong
app.post('/users', [
   UsersController.insert
]);
37

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
5

Câu trả lời sẽ giống như thế này

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
20

Lưu ý rằng chúng ta có thể thấy mật khẩu băm. Đối với hướng dẫn này, chúng tôi đang hiển thị mật khẩu, nhưng cách tốt nhất là không bao giờ tiết lộ mật khẩu, ngay cả khi nó đã được băm. Một thứ khác mà chúng ta có thể thấy là

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
8, mà chúng ta sẽ sử dụng để xử lý các quyền của người dùng sau này

Lặp lại mô hình đã trình bày ở trên, bây giờ chúng ta có thể thêm chức năng cập nhật người dùng. Chúng tôi sẽ sử dụng hoạt động

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
0 vì nó sẽ cho phép chúng tôi chỉ gửi các trường mà chúng tôi muốn thay đổi. tàu tốc hành. js, do đó, sẽ là
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
0 đến
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
06 và chúng tôi sẽ gửi bất kỳ trường nào chúng tôi muốn thay đổi. Chúng tôi cũng sẽ cần triển khai một số xác thực bổ sung vì các thay đổi sẽ bị hạn chế đối với người dùng được đề cập hoặc quản trị viên và chỉ quản trị viên mới có thể thay đổi
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
8. Bây giờ chúng tôi sẽ bỏ qua điều đó và quay lại với nó sau khi chúng tôi triển khai mô-đun xác thực. Hiện tại, bộ điều khiển của chúng ta sẽ trông như thế này

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
21

Theo mặc định, chúng tôi sẽ gửi mã HTTP 204 không có nội dung phản hồi để cho biết rằng yêu cầu đã thành công

Và chúng ta sẽ cần thêm phương thức

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
08 vào mô hình

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
22

Bộ điều khiển sau sẽ triển khai danh sách người dùng dưới dạng

app.post('/users', [
   UsersController.insert
]);
8 tại
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
20

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
23

Phương pháp mô hình tương ứng sẽ là

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
24

Phản hồi danh sách kết quả sẽ có cấu trúc sau

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
25

Và phần cuối cùng được thực hiện là

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
1 tại
app.post('/users', [
   UsersController.insert
]);
34

Bộ điều khiển của chúng tôi để xóa sẽ là

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
26

Tương tự như trước đây, bộ điều khiển sẽ trả về mã HTTP 204 và không có phần nội dung nào dưới dạng xác nhận

Phương pháp mô hình tương ứng sẽ giống như thế này

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
27

Bây giờ chúng tôi có tất cả các thao tác cần thiết để thao tác với tài nguyên người dùng và chúng tôi đã hoàn thành với bộ điều khiển người dùng. Ý tưởng chính của mã này là cung cấp cho bạn các khái niệm cốt lõi về việc sử dụng mẫu REST. Chúng tôi sẽ cần quay lại mã này để triển khai một số xác thực và quyền đối với mã đó, nhưng trước tiên, chúng tôi cần bắt đầu xây dựng bảo mật của mình. Hãy tạo mô-đun auth

Tạo mô-đun xác thực

Trước khi chúng tôi có thể bảo mật mô-đun

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
2 bằng cách triển khai phần mềm trung gian cấp phép và xác thực, chúng tôi cần có khả năng tạo mã thông báo hợp lệ cho người dùng hiện tại. Chúng tôi sẽ tạo JWT để phản hồi người dùng cung cấp email và mật khẩu hợp lệ. JWT cho phép người dùng thực hiện một số yêu cầu một cách an toàn mà không cần xác thực nhiều lần. Nó thường có thời gian hết hạn và mã thông báo mới được tạo lại cứ sau vài phút để giữ an toàn cho liên lạc. Tuy nhiên, đối với hướng dẫn này, chúng tôi sẽ bỏ qua việc làm mới mã thông báo và giữ cho nó đơn giản với một mã thông báo cho mỗi lần đăng nhập

Trước tiên, chúng tôi sẽ tạo một điểm cuối cho các yêu cầu của

app.post('/users', [
   UsersController.insert
]);
7 đối với tài nguyên
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
25. Nội dung yêu cầu sẽ chứa email và mật khẩu của người dùng

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
28

Trước khi chúng tôi sử dụng bộ điều khiển, chúng tôi nên xác thực người dùng trong

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
26

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
29

Làm xong việc đó, chúng ta có thể chuyển sang bộ điều khiển và tạo JWT

app.post('/users', [
   UsersController.insert
]);
0

Mặc dù chúng tôi sẽ không làm mới mã thông báo trong hướng dẫn này, nhưng bộ điều khiển đã được thiết lập để cho phép tạo mã thông báo đó nhằm giúp triển khai mã thông báo dễ dàng hơn trong quá trình phát triển tiếp theo

Tất cả những gì chúng ta cần bây giờ là tạo Express. js và gọi phần mềm trung gian thích hợp trong

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
27

app.post('/users', [
   UsersController.insert
]);
1

Phản hồi sẽ chứa JWT được tạo trong trường accessToken

app.post('/users', [
   UsersController.insert
]);
2

Sau khi tạo mã thông báo, chúng tôi có thể sử dụng nó bên trong tiêu đề

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
28 bằng cách sử dụng biểu mẫu
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
29

Tạo quyền và xác nhận phần mềm trung gian

Điều đầu tiên chúng ta nên xác định là ai có thể sử dụng tài nguyên

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
2. Đây là những tình huống mà chúng ta sẽ cần phải xử lý

  • Công khai để tạo người dùng (quy trình đăng ký). Chúng tôi sẽ không sử dụng JWT cho kịch bản này
  • Riêng tư đối với người dùng đã đăng nhập và để quản trị viên cập nhật người dùng đó
  • Chỉ dành riêng cho quản trị viên để xóa tài khoản người dùng

Khi đã xác định được các tình huống này, trước tiên chúng tôi sẽ yêu cầu một phần mềm trung gian luôn xác thực người dùng nếu họ đang sử dụng JWT hợp lệ. Phần mềm trung gian trong

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
51 có thể đơn giản như

app.post('/users', [
   UsersController.insert
]);
3

Chúng tôi sẽ sử dụng mã lỗi HTTP để xử lý lỗi yêu cầu

  • HTTP 401 cho một yêu cầu không hợp lệ
  • HTTP 403 cho yêu cầu hợp lệ có mã thông báo không hợp lệ hoặc mã thông báo hợp lệ có quyền không hợp lệ

Chúng ta có thể sử dụng toán tử AND (bitmasking) để kiểm soát các quyền. Nếu chúng ta đặt mỗi quyền được yêu cầu là lũy thừa của 2, thì chúng ta có thể coi mỗi bit của số nguyên 32 bit là một quyền duy nhất. Sau đó, quản trị viên có thể có tất cả các quyền bằng cách đặt giá trị quyền của họ thành 2147483647. Người dùng đó sau đó có thể có quyền truy cập vào bất kỳ tuyến đường nào. Một ví dụ khác, người dùng có giá trị quyền được đặt thành 7 sẽ có quyền đối với các vai trò được đánh dấu bằng bit cho các giá trị 1, 2 và 4 (hai lũy thừa của 0, 1 và 2)

Phần mềm trung gian cho điều đó sẽ trông như thế này

app.post('/users', [
   UsersController.insert
]);
4

Phần mềm trung gian là chung chung. Nếu cấp độ quyền của người dùng và cấp độ quyền được yêu cầu trùng nhau ít nhất một bit, thì kết quả sẽ lớn hơn 0 và chúng tôi có thể để hành động tiếp tục;

Bây giờ, chúng ta cần thêm phần mềm trung gian xác thực vào các tuyến mô-đun của người dùng trong

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
52

app.post('/users', [
   UsersController.insert
]);
5

Điều này kết thúc sự phát triển cơ bản của Node của chúng tôi. API REST của js. Tất cả những gì còn lại phải làm là kiểm tra tất cả

Chạy và thử nghiệm với chứng mất ngủ

Insomnia là một ứng dụng khách REST phù hợp với phiên bản miễn phí tốt. Tất nhiên, cách tốt nhất là bao gồm các bài kiểm tra mã và triển khai báo cáo lỗi thích hợp trong dự án, nhưng các ứng dụng khách REST của bên thứ ba rất phù hợp để thử nghiệm và triển khai các giải pháp của bên thứ ba khi không có báo cáo lỗi và gỡ lỗi dịch vụ. Chúng tôi sẽ sử dụng nó ở đây để đóng vai trò của một ứng dụng và hiểu rõ hơn về những gì đang diễn ra với API của chúng tôi

Để tạo người dùng, chúng ta chỉ cần

app.post('/users', [
   UsersController.insert
]);
7 các trường bắt buộc đến điểm cuối phù hợp và lưu trữ ID được tạo để sử dụng tiếp theo

Request with the appropriate data for creating a user

API sẽ phản hồi với ID người dùng

Confirmation response with userID

Bây giờ chúng ta có thể tạo JWT bằng cách sử dụng điểm cuối

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
54

Request with login data

Chúng tôi sẽ nhận được một mã thông báo như phản hồi của chúng tôi

Confirmation containing the corresponding JSON Web Token

Lấy

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
55, đặt trước nó bằng
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
56 (nhớ khoảng trắng) và thêm nó vào tiêu đề yêu cầu bên dưới
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
28

Setting up the headers to transfer contain the authenticating JWT

Nếu chúng tôi không làm điều này ngay bây giờ vì chúng tôi đã triển khai phần mềm trung gian cấp phép, mọi yêu cầu ngoài đăng ký sẽ trả về mã HTTP 401. Tuy nhiên, với mã thông báo hợp lệ, chúng tôi nhận được phản hồi sau từ

app.post('/users', [
   UsersController.insert
]);
34

Response listing the data for the indicated user

Như đã đề cập trước đây, chúng tôi đang hiển thị tất cả các trường cho mục đích giáo dục và vì mục đích đơn giản. Mật khẩu (được băm hoặc cách khác) sẽ không bao giờ hiển thị trong phản hồi

Hãy thử lấy danh sách người dùng

Request for a list of all users

Bất ngờ. Chúng tôi nhận được phản hồi 403

Action refused due to lack of appropriate permission level

Người dùng của chúng tôi không có quyền truy cập điểm cuối này. Chúng tôi sẽ cần thay đổi

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
8 của người dùng từ 1 thành 7 (hoặc thậm chí 5 cũng được, vì các cấp quyền miễn phí và trả phí của chúng tôi được biểu thị lần lượt là 1 và 4. ) Chúng tôi có thể thực hiện việc này theo cách thủ công trong MongoDB, tại dấu nhắc tương tác của nó, như thế này (với ID được thay đổi thành kết quả cục bộ của bạn)

app.post('/users', [
   UsersController.insert
]);
6

Bây giờ chúng ta cần tạo một JWT mới

Sau khi hoàn thành, chúng tôi nhận được phản hồi thích hợp

Response with all users and their data

Tiếp theo, hãy kiểm tra chức năng cập nhật bằng cách gửi yêu cầu

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
0 với một số trường đến điểm cuối
app.post('/users', [
   UsersController.insert
]);
34 của chúng tôi

Request containing partial data to be updated

Chúng tôi mong đợi phản hồi 204 để xác nhận thao tác thành công nhưng chúng tôi có thể yêu cầu người dùng xác minh lại một lần nữa

Response after successful change

Cuối cùng, chúng ta cần xóa người dùng. Chúng tôi sẽ cần tạo một người dùng mới như được mô tả ở trên (đừng quên lưu ý ID người dùng) và đảm bảo rằng chúng tôi có JWT phù hợp cho người dùng quản trị viên. Người dùng mới sẽ cần đặt quyền của họ thành 2053 (tức là 2048—

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
202—cộng với 5 trước đó của chúng tôi) để có thể thực hiện thao tác xóa. Khi điều đó được thực hiện và JWT mới được tạo, chúng tôi sẽ phải cập nhật tiêu đề yêu cầu
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
28 của mình

Request setup for deleting a user

Gửi yêu cầu

exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
1 tới
app.post('/users', [
   UsersController.insert
]);
34, chúng tôi sẽ nhận được phản hồi 204 dưới dạng xác nhận. Một lần nữa, chúng tôi có thể xác minh bằng cách yêu cầu
exports.insert = (req, res) => {
   let salt = crypto.randomBytes(16).toString('base64');
   let hash = crypto.createHmac('sha512',salt)
                                    .update(req.body.password)
                                    .digest("base64");
   req.body.password = salt + "$" + hash;
   req.body.permissionLevel = 1;
   UserModel.createUser(req.body)
       .then((result) => {
           res.status(201).send({id: result._id});
       });
};
20 từ máy chủ API Node của chúng tôi để liệt kê tất cả người dùng hiện có

Nút. Hướng dẫn về máy chủ API js. Bước tiếp theo

Với các công cụ và phương pháp được đề cập trong hướng dẫn này, giờ đây bạn có thể tạo Node đơn giản và an toàn. API REST của js. Rất nhiều phương pháp hay nhất không cần thiết cho quy trình đã bị bỏ qua, vì vậy đừng quên

  • Thực hiện xác nhận thích hợp (e. g. , đảm bảo rằng email của người dùng là duy nhất)
  • Thực hiện kiểm tra đơn vị và báo cáo lỗi
  • Ngăn người dùng thay đổi cấp độ quyền của chính họ
  • Ngăn quản trị viên tự xóa
  • Ngăn chặn tiết lộ thông tin nhạy cảm (e. g. , mật khẩu băm)
  • Di chuyển bí mật JWT từ
    exports.insert = (req, res) => {
       let salt = crypto.randomBytes(16).toString('base64');
       let hash = crypto.createHmac('sha512',salt)
                                        .update(req.body.password)
                                        .digest("base64");
       req.body.password = salt + "$" + hash;
       req.body.permissionLevel = 1;
       UserModel.createUser(req.body)
           .then((result) => {
               res.status(201).send({id: result._id});
           });
    };
    
    207 sang cơ chế phân phối bí mật ngoài repo, không dựa trên môi trường

Một bài tập cuối cùng dành cho người đọc có thể là chuyển đổi Node. js cơ sở mã máy chủ API từ việc sử dụng lời hứa JavaScript của nó đối với kỹ thuật async/await

Đối với những người bạn có thể quan tâm đến việc đưa API JavaScript REST của họ lên cấp độ tiếp theo, giờ đây chúng tôi cũng có phiên bản TypeScript của Nút này. dự án hướng dẫn API js


Đọc thêm trên Blog Kỹ thuật Toptal

  • 5 điều bạn chưa từng làm với đặc tả REST

Thẻ

JavaScript nhanh. jsRESTNode. js

Người làm việc tự do? Tìm công việc tiếp theo của bạn.

Nút. Việc làm lập trình viên js

Xem thông tin đầy đủ

Marcos Henrique da Silva

Nhà phát triển JavaScript

Giới thiệu về tác giả

Marcos đam mê phát triển full-stack, kiến ​​trúc REST và phương pháp Agile, và JavaScript là ngôn ngữ lập trình chính của anh ấy. Marcos đã làm việc với CNTT từ năm 2003 và trong vài năm qua, anh ấy hầu như chỉ làm việc với công nghệ phần mềm và tập trung vào các ứng dụng web. Marcos chuyên về JavaScript, sử dụng các framework SPA như AngularJS, Angular, React và Node. js để phát triển back-end. Marcos cũng đã làm việc với các ứng dụng Android gốc và PHP

Thuê Marcos

Bình luận

Вячеслав Москаленко

Câu trả lời sẽ như thế này. { "họ". "Marcos", "Họ". "Silva", "thư điện tử". "các quan chức. henrique@toptal. com", "mật khẩu". "Y+XZEaR7J8xAQCc37nf1rw==$p8b5ykUx6xpC6k8MryDaRmXDxncLumU9mEVabyLdpotO66Qjh0igVOVerdqAh+CUQ4n/E0z48mp8SDTpX2ivuQ==", "mức quyền". 1, "danh tính". "5b02c5c84817bf28049e58a3" } Trước khi chúng tôi chuyển đổi kết quả thành kết quả theo cách thủ công. toJSON() và xóa các trường _id và __v (trường sau được thêm bởi cầy mangut). Có hai câu hỏi ở đây. a) trường 'id' (không phải _id) đến từ đâu? . b) tại sao lại xóa _id và __v theo cách thủ công nếu chúng tôi có thể sử dụng phép chiếu?

Вячеслав Москаленко

Câu trả lời sẽ như thế này. { "họ". "Marcos", "Họ". "Silva", "thư điện tử". "các quan chức. henrique@toptal. com", "mật khẩu". "Y+XZEaR7J8xAQCc37nf1rw==$p8b5ykUx6xpC6k8MryDaRmXDxncLumU9mEVabyLdpotO66Qjh0igVOVerdqAh+CUQ4n/E0z48mp8SDTpX2ivuQ==", "mức quyền". 1, "danh tính". "5b02c5c84817bf28049e58a3" } Trước khi chúng tôi chuyển đổi kết quả thành kết quả theo cách thủ công. toJSON() và xóa các trường _id và __v (trường sau được thêm bởi cầy mangut). Có hai câu hỏi ở đây. a) trường 'id' (không phải _id) đến từ đâu? . b) tại sao lại xóa _id và __v theo cách thủ công nếu chúng tôi có thể sử dụng phép chiếu?

Вячеслав Москаленко

xuất khẩu. patchUser = (id, userData) => { return new Promise((resolve, reject) => { User. findById(id, function (err, user) { if (err) reject(err); for (let i in userData) { user[i] = userData[i]; } user. lưu (hàm (err, người dùng đã cập nhật) { if (err) trả về từ chối (err); giải quyết (người dùng đã cập nhật); }); . a) sử dụng 'findOneAndUpdate' (http. // mongoosejs. com/docs/api. html#model_Mô hình. findOneAndUpdate) được tích hợp vào cầy mangut; . xuất khẩu. patchUser = (id, userData) => { return Người dùng. findOneAndUpdate({ _id. id }, dữ liệu người dùng); . findOneAndUpdate trả về cho chúng tôi một Truy vấn, có phương thức then, do đó chúng tôi có thể sử dụng nó như một lời hứa

Вячеслав Москаленко

xuất khẩu. patchUser = (id, userData) => { return new Promise((resolve, reject) => { User. findById(id, function (err, user) { if (err) reject(err); for (let i in userData) { user[i] = userData[i]; } user. lưu (hàm (err, người dùng đã cập nhật) { if (err) trả về từ chối (err); giải quyết (người dùng đã cập nhật); }); . a) sử dụng 'findOneAndUpdate' (http. // mongoosejs. com/docs/api. html#model_Mô hình. findOneAndUpdate) được tích hợp vào cầy mangut; . xuất khẩu. patchUser = (id, userData) => { return Người dùng. findOneAndUpdate({ _id. id }, dữ liệu người dùng); . findOneAndUpdate trả về cho chúng tôi một Truy vấn, có phương thức then, do đó chúng tôi có thể sử dụng nó như một lời hứa

Ernesto Jimenez

Đây là một hướng dẫn tuyệt vời. Cám ơn vì đã chia sẻ

Ernesto Jimenez

Đây là một hướng dẫn tuyệt vời. Cám ơn vì đã chia sẻ

kỷ niệm

Bạn không nên sử dụng phương thức mã hóa của riêng mình. Nếu bạn phải lưu trữ mật khẩu, thì Argon2 là cách tốt nhất hiện tại. Dưới đây là danh sách các nguyên tắc PHẢI được thi hành khi xây dựng hệ thống xác thực. https. //www. con ong bắp cày. tổ chức/chỉ mục. php/Password_Storage_Cheat_Sheet https. //www. con ong bắp cày. tổ chức/chỉ mục. php/Xác thực_Cheat_Sheet

kỷ niệm

Bạn không nên sử dụng phương thức mã hóa của riêng mình. Nếu bạn phải lưu trữ mật khẩu, thì Argon2 là cách tốt nhất hiện tại. Dưới đây là danh sách các nguyên tắc PHẢI được thi hành khi xây dựng hệ thống xác thực. https. //www. con ong bắp cày. tổ chức/chỉ mục. php/Password_Storage_Cheat_Sheet https. //www. con ong bắp cày. tổ chức/chỉ mục. php/Xác thực_Cheat_Sheet

Bến tàu Paolo Fumagalli

While I second the idea of using Argon2 (or Srypt for that matter), if we want to use something built into node, we should be using at least PBKDF2 with SHA512 and at least 100,000 rounds. Normally my code looks somehow like this:

 const ALGORITHM = 'sha512' const ENCODING = 'utf-8' const ROUNDS = 100000 const LENGTH = 64 // size of sha512 .. let saltBuffer = crypto.randomBytes(LENGTH) let secretBuffer = new Buffer(password, ENCODING) crypto.pbkdf2(secretBuffer, saltBuffer, ROUNDS, LENGTH, ALGORITHM, (error, hashBuffer) => { if (error) return reject(error) return resolve([ ALGORITHM, ROUNDS, saltBuffer.toString('hex'), hashBuffer.toString('hex'), ].join(',')) }) 

Bến tàu Paolo Fumagalli

While I second the idea of using Argon2 (or Srypt for that matter), if we want to use something built into node, we should be using at least PBKDF2 with SHA512 and at least 100,000 rounds. Normally my code looks somehow like this:

 const ALGORITHM = 'sha512' const ENCODING = 'utf-8' const ROUNDS = 100000 const LENGTH = 64 // size of sha512 .. let saltBuffer = crypto.randomBytes(LENGTH) let secretBuffer = new Buffer(password, ENCODING) crypto.pbkdf2(secretBuffer, saltBuffer, ROUNDS, LENGTH, ALGORITHM, (error, hashBuffer) => { if (error) return reject(error) return resolve([ ALGORITHM, ROUNDS, saltBuffer.toString('hex'), hashBuffer.toString('hex'), ].join(',')) }) 

Austin Condiff

Xin chào Marcos, hướng dẫn tuyệt vời nhưng bạn không đề cập đến cách định cấu hình máy chủ của mình. js để sử dụng các tệp chúng tôi đã tạo trong hướng dẫn này

Austin Condiff

Xin chào Marcos, hướng dẫn tuyệt vời nhưng bạn không đề cập đến cách định cấu hình máy chủ của mình. js để sử dụng các tệp chúng tôi đã tạo trong hướng dẫn này

Vedran Aberle Tokić

Có một dự án gitHub được liên kết ở cuối bài viết sẽ lấp đầy các khoảng trống

Vedran Aberle Tokić

Có một dự án gitHub được liên kết ở cuối bài viết sẽ lấp đầy các khoảng trống

Des

Bài báo tuyệt vời Marcos, rất thích đọc nó. Tốt lắm

Des

Bài báo tuyệt vời Marcos, rất thích đọc nó. Tốt lắm

Mark Spencer

Tại thời điểm này, tôi rất vui ( deepwebservice01 AT gmail DOT com ) đã nhận được tín dụng của tôi ở nơi cần đến. Trong vài ngày qua, tôi đã theo dõi lần lượt từng mục tiêu cực cũ trong báo cáo của mình đã giảm xuống và điểm số của tôi tăng lên và đạt mức xuất sắc. Tôi cảm ơn họ vì đã làm việc chăm chỉ và sẽ giới thiệu dịch vụ của họ cho mọi người vì họ cũng hỗ trợ tín dụng của họ

Mark Spencer

Tại thời điểm này, tôi rất vui ( deepwebservice01 AT gmail DOT com ) đã nhận được tín dụng của tôi ở nơi cần đến. Trong vài ngày qua, tôi đã theo dõi lần lượt từng mục tiêu cực cũ trong báo cáo của mình đã giảm xuống và điểm số của tôi tăng lên và đạt mức xuất sắc. Tôi cảm ơn họ vì đã làm việc chăm chỉ và sẽ giới thiệu dịch vụ của họ cho mọi người vì họ cũng hỗ trợ tín dụng của họ

Bruno Carletti

Xin chào Marcos, hướng dẫn tuyệt vời. Cảm ơn vì điều đó. Bạn nghĩ gì về việc đặt tiêu đề "Vị trí" để phản hồi phương thức POST?

Bruno Carletti

Xin chào Marcos, hướng dẫn tuyệt vời. Cảm ơn vì điều đó. Bạn nghĩ gì về việc đặt tiêu đề "Vị trí" để phản hồi phương thức POST?

Vishal gangwar

Xin chào Hướng dẫn tuyệt vời về Macros, nhưng bạn đã không đề cập đến cách sử dụng độ vênh trong dự án này

Vishal gangwar

Xin chào Hướng dẫn tuyệt vời về Macros, nhưng bạn đã không đề cập đến cách sử dụng độ vênh trong dự án này

Bruno Santana

Xin chào. Tôi đoán hướng dẫn này phù hợp hơn với các nhà phát triển đã quen thuộc với express js, phải không? . Phải tải xuống phiên bản đầy đủ từ github và DIFF thư mục, để nhận được các đoạn mã không có trong hướng dẫn. =]

Bruno Santana

Xin chào. Tôi đoán hướng dẫn này phù hợp hơn với các nhà phát triển đã quen thuộc với express js, phải không? . Phải tải xuống phiên bản đầy đủ từ github và DIFF thư mục, để nhận được các đoạn mã không có trong hướng dẫn. =]

nguyễn đình trung

Cảm ơn Marcos rất nhiều vì một hướng dẫn tuyệt vời

nguyễn đình trung

Cảm ơn Marcos rất nhiều vì một hướng dẫn tuyệt vời

Lem Mikee

Xin chào. Hướng dẫn này rất hữu ích nhưng nó được đánh giá cao bởi những nhà phát triển đã quen thuộc hoặc đã sử dụng expressJs trước đây. Nếu người đọc không biết gì về MongoDb, NodeJs, ExpressJs thì sẽ rất hỗn loạn

Lem Mikee

Xin chào. Hướng dẫn này rất hữu ích nhưng nó được đánh giá cao bởi những nhà phát triển đã quen thuộc hoặc đã sử dụng expressJs trước đây. Nếu người đọc không biết gì về MongoDb, NodeJs, ExpressJs thì sẽ rất hỗn loạn

nguyễn trường sơn

Xin chào Bro, cảm ơn vì hướng dẫn tuyệt vời của bạn. Tuy nhiên, tuyến /auth/refresh có lỗi "Khóa phải là bộ đệm,. xác thực. Thẩm định. phần mềm trung gian. js" bạn có thể kiểm tra nó không?

nguyễn trường sơn

Xin chào Bro, cảm ơn vì hướng dẫn tuyệt vời của bạn. Tuy nhiên, tuyến /auth/refresh có lỗi "Khóa phải là bộ đệm,. xác thực. Thẩm định. phần mềm trung gian. js" bạn có thể kiểm tra nó không?

4nealalan

Tôi cảm thấy như đây có thể là hướng dẫn về nút thứ 7 mà tôi đã cố gắng thực hiện nhưng nó còn thiếu một số phần lớn ngay từ đầu. Nó chỉ sụp đổ trong phần Cài đặt. Thất vọng

4nealalan

Tôi cảm thấy như đây có thể là hướng dẫn về nút thứ 7 mà tôi đã cố gắng thực hiện nhưng nó còn thiếu một số phần lớn ngay từ đầu. Nó chỉ sụp đổ trong phần Cài đặt. Thất vọng

Marcos Henrique da Silva

Xin chào, phần nào bạn gặp sự cố khi thiết lập dự án?

Marcos Henrique da Silva

Xin chào, phần nào bạn gặp sự cố khi thiết lập dự án?

Marcos Henrique da Silva

Xin chào Lem, cảm ơn phản hồi của bạn. Tôi phải đồng ý với lập luận của bạn. Điểm chính của bài viết là chỉ ra một cách đơn giản để tạo một ứng dụng cơ bản REST mà không cần đi sâu vào phần cụ thể của NodeJS, MongoDb và Express. Đối với các bài viết tiếp theo, tôi sẽ cung cấp đánh giá tốt hơn cho từng thành phần tôi sẽ sử dụng cho bài viết

Marcos Henrique da Silva

Xin chào Lem, cảm ơn phản hồi của bạn. Tôi phải đồng ý với lập luận của bạn. Điểm chính của bài viết là chỉ ra một cách đơn giản để tạo một ứng dụng cơ bản REST mà không cần đi sâu vào phần cụ thể của NodeJS, MongoDb và Express. Đối với các bài viết tiếp theo, tôi sẽ cung cấp đánh giá tốt hơn cho từng thành phần tôi sẽ sử dụng cho bài viết

Marcos Henrique da Silva

Cảm ơn

Marcos Henrique da Silva

Cảm ơn

Marcos Henrique da Silva

Xin chào Vishal, cảm ơn vì phản hồi. Mặc dù gói. json có sự vênh vang ở đó tôi đã không tập trung vào nó để hiển thị như một ví dụ về cách sử dụng. Tôi sẽ cố gắng cung cấp một ví dụ hay trong nút tiếp theo. bài viết js

Marcos Henrique da Silva

Xin chào Vishal, cảm ơn vì phản hồi. Mặc dù gói. json có sự vênh vang ở đó tôi đã không tập trung vào nó để hiển thị như một ví dụ về cách sử dụng. Tôi sẽ cố gắng cung cấp một ví dụ hay trong nút tiếp theo. bài viết js

Marcos Henrique da Silva

Đó là một mô hình tốt mà tôi đã tránh trong bài viết này. Cảm ơn vì đã chỉ nó Bruno

Marcos Henrique da Silva

Đó là một mô hình tốt mà tôi đã tránh trong bài viết này. Cảm ơn vì đã chỉ nó Bruno

Marcos Henrique da Silva

Cảm ơn bạn

Marcos Henrique da Silva

Cảm ơn bạn

Marcos Henrique da Silva

Xin chào, xin lỗi vì sự chậm trễ. Tôi đã cập nhật kho lưu trữ với một bản sửa lỗi ở đó

Marcos Henrique da Silva

Xin chào, xin lỗi vì sự chậm trễ. Tôi đã cập nhật kho lưu trữ với một bản sửa lỗi ở đó

Marcos Henrique da Silva

Xin chào, tôi đã nhanh chóng bảo trì mã và chấp nhận một số yêu cầu kéo. Nó nên được tất cả làm việc từ đầu. Cảm ơn vì bạn đã phản hồi

Marcos Henrique da Silva

Xin chào, tôi đã nhanh chóng bảo trì mã và chấp nhận một số yêu cầu kéo. Nó nên được tất cả làm việc từ đầu. Cảm ơn vì bạn đã phản hồi

Vishwas C

Bài viết hay và tôi thích cuộc trò chuyện bên dưới về việc sử dụng các mã hóa khác nhau. Một gợi ý sẽ là bảo mật env. cấu hình. js để sử dụng thông tin xác thực trong thời gian chạy từ env thời gian chạy, tôi thấy rằng bạn đã jwt. bí mật = "bí mật của bạn" được thêm vào env. cấu hình. js, tôi không chắc đó có phải là cách tốt nhất để lưu trữ thông tin xác thực trong tệp JS không

Vishwas C

Bài viết hay và tôi thích cuộc trò chuyện bên dưới về việc sử dụng các mã hóa khác nhau. Một gợi ý sẽ là bảo mật env. cấu hình. js để sử dụng thông tin xác thực trong thời gian chạy từ env thời gian chạy, tôi thấy rằng bạn đã jwt. bí mật = "bí mật của bạn" được thêm vào env. cấu hình. js, tôi không chắc đó có phải là cách tốt nhất để lưu trữ thông tin xác thực trong tệp JS không

Raghav Arora

Xin chào Marcos, Bạn đã tạo một blog tuyệt vời cho loại hướng dẫn này như API

Raghav Arora

Xin chào Marcos, Bạn đã tạo một blog tuyệt vời cho loại hướng dẫn này như API

Rodney Barbati

Chưa bao giờ viết ứng dụng nút js, điều này thực sự hoàn toàn khó hiểu. Tôi nghĩ rằng bạn đang nói rằng một mô-đun là một cấu trúc phía máy chủ. Một mô-đun chứa các tuyến và bộ điều khiển, cả hai đều được viết bằng javascript và chứa trong các tệp khác nhau. Bạn đặt các tuyến đường của bạn trong một tuyến đường. cấu hình. js và bộ điều khiển của bạn trong một tệp khác. Bạn xuất từng phương thức điều khiển của mình để cung cấp chúng cho các tuyến sử dụng. Các tuyến xác định điểm cuối REST trên máy chủ. Các điểm cuối này thực hiện chức năng của chúng bằng cách gọi các phương thức trên bộ điều khiển mô-đun. Mô hình mà bạn tiếp tục đề cập đến dường như là một mô hình dữ liệu nằm trong trình duyệt và sẽ cấu thành phiên của người dùng (hoặc một phần của nó). Giao diện người dùng của bạn sẽ gọi các phương thức trên mô hình, sau đó sẽ thực hiện các cuộc gọi HTTP đến các tuyến được xác định trên máy chủ, sẽ xử lý các tham số đã truyền bằng cách gọi các phương thức của bộ điều khiển. Về phần nào của toàn bộ đang được hỗ trợ bởi express hoặc cầy mangut hoặc các thư viện khác, điều đó không rõ ràng chút nào. Về cơ bản, không có cách nào để nhà phát triển nút mới biết phần nào là nút gốc và phần nào là express hoặc cầy mangut. Thậm chí không rõ liệu bạn có thực sự có thể tạo các dịch vụ REST chỉ bằng Node hay không

Rodney Barbati

Chưa bao giờ viết ứng dụng nút js, điều này thực sự hoàn toàn khó hiểu. Tôi nghĩ rằng bạn đang nói rằng một mô-đun là một cấu trúc phía máy chủ. Một mô-đun chứa các tuyến và bộ điều khiển, cả hai đều được viết bằng javascript và chứa trong các tệp khác nhau. Bạn đặt các tuyến đường của bạn trong một tuyến đường. cấu hình. js và bộ điều khiển của bạn trong một tệp khác. Bạn xuất từng phương thức điều khiển của mình để cung cấp chúng cho các tuyến sử dụng. Các tuyến xác định điểm cuối REST trên máy chủ. Các điểm cuối này thực hiện chức năng của chúng bằng cách gọi các phương thức trên bộ điều khiển mô-đun. Mô hình mà bạn tiếp tục đề cập đến dường như là một mô hình dữ liệu nằm trong trình duyệt và sẽ cấu thành phiên của người dùng (hoặc một phần của nó). Giao diện người dùng của bạn sẽ gọi các phương thức trên mô hình, sau đó sẽ thực hiện các cuộc gọi HTTP đến các tuyến được xác định trên máy chủ, sẽ xử lý các tham số đã truyền bằng cách gọi các phương thức của bộ điều khiển. Về phần nào của toàn bộ đang được hỗ trợ bởi express hoặc cầy mangut hoặc các thư viện khác, điều đó không rõ ràng chút nào. Về cơ bản, không có cách nào để nhà phát triển nút mới biết phần nào là nút gốc và phần nào là express hoặc cầy mangut. Thậm chí không rõ liệu bạn có thực sự có thể tạo các dịch vụ REST chỉ bằng Node hay không

Noha Amr

làm thế nào để thực hiện thử nghiệm đơn vị?

Noha Amr

làm thế nào để thực hiện thử nghiệm đơn vị?

loai amer

Xin chào Marcos, tôi đã bị mất điểm khi chạy máy chủ và kiểm tra, bạn có thể vui lòng giải thích bạn đã làm điều đó như thế nào không?

loai amer

Xin chào Marcos, tôi đã bị mất điểm khi chạy máy chủ và kiểm tra, bạn có thể vui lòng giải thích bạn đã làm điều đó như thế nào không?

Marcos Henrique da Silva

Xin chào Rodney, Trước hết xin cảm ơn phản hồi lịch sự và xin lỗi vì đã chậm trễ trả lời bạn. Theo nhận xét của bạn, tôi phải nói lời xin lỗi vì đã phá vỡ những kỳ vọng về công nghệ mà tôi đã sử dụng trên bài báo và cách tôi viết. Tôi đã mong người đọc quen thuộc với Node. Kiến trúc JS để đọc bài viết này. Ý tưởng chính của bài viết là thực hành để tạo thiết lập ban đầu cho API REST bằng Node. JS. Lúc đầu đã được viết rằng chúng tôi sẽ sử dụng express. js như một framework được lựa chọn để tăng tốc độ phát triển của chúng tôi nhưng thật không may, một số người đã hiểu sai về nó. Cách suy nghĩ của bạn về các mô-đun gần như chính xác. Một mô-đun có thể được định nghĩa là một phần của chương trình có thể thực hiện một thói quen cụ thể. Trong một kịch bản lớn hơn, tôi thiết lập ba thư mục để gọi dưới dạng mô-đun cho từng quy trình. thói quen chia sẻ, người dùng và xác thực. Giữa mỗi mô-đun, tôi đã đột nhập vào các mô-đun khác để có thể có một số đoạn mã nên thực hiện quy trình tối thiểu để tránh bảo trì mã kém. Đối với phần REST, đây là kiểu 'cách xây dựng API'. Những gì chúng tôi xây dựng trong bài viết này là điểm khởi đầu đơn giản về cách bạn có thể xử lý nó ở phía sau để phục vụ một số ứng dụng khách khác nhau (chẳng hạn như Postman, Insomnia, Angular, React và bất kỳ loại công nghệ nào có thể gọi API này). Mặc dù tôi đã giải thích ngắn gọn về REST, nhưng có rất nhiều thông tin còn thiếu cần tránh để tạo ra một bài viết lớn đi từ chủ đề thực hành. Về điểm tin nhắn cuối cùng của bạn "Theo như những phần nào của toàn bộ đang được hỗ trợ bởi express hoặc cầy mangut hoặc các thư viện khác, hoàn toàn không rõ ràng. " MỘT. Cảm ơn một lần nữa vì phản hồi và thực sự trong bài viết ở đây không có lời giải thích thích hợp nào về nó và tôi sẽ cố gắng cải thiện cho các bài viết tiếp theo mà tôi có thể viết. "Về cơ bản, không có cách nào để nhà phát triển nút mới biết phần nào là nút gốc và phần nào là express hoặc cầy mangut. " MỘT. Một lần nữa, cảm ơn vì phản hồi. Tôi đã mong đợi những độc giả biết ít nhất cơ bản về Node. JS vì điều đó là đủ để biết cái nào là express và cái nào là mongoose, v.v. Mặc dù mục đích của bài viết là không dạy thư viện nào là gì, nhưng tôi hiểu quan điểm của bạn và tôi sẽ tiếp tục làm việc trong các bài viết tiếp theo của mình để rõ ràng hơn về điều đó. "Không rõ liệu bạn có thực sự có thể tạo các dịch vụ REST chỉ bằng Node hay không. " MỘT. Tôi đoán rằng quan điểm của bạn là nếu chúng ta có thể hoặc không thể tạo các dịch vụ REST mà không sử dụng Node thuần túy. Mã JS, tránh mọi thư viện bổ sung. Nếu đó là vấn đề, tôi sẽ nói rằng vì chúng tôi đang sử dụng một nút. thư viện js (nhanh. js) được xây dựng với nút. js và cho nút. js, thì đúng là chúng ta có thể xây dựng các dịch vụ REST chỉ bằng Node. Nếu bạn muốn tránh tất cả sự trừu tượng, tôi khuyên bạn nên truy cập mô-đun nút http (https. //nodejs. tổ chức/api/http. html) và cố gắng tạo những gì thể hiện. js đã giúp chúng ta dễ dàng hơn trong quá trình phát triển để hiểu rõ hơn về phần này. Tôi đánh giá cao mối quan tâm của bạn về bài viết này và tôi hy vọng rằng bạn có những nghi ngờ rõ ràng hơn một chút về nó. Trân trọng,

Marcos Henrique da Silva

Xin chào Vishwas, Quả thực là một thông lệ tồi. Vì mục đích của bài viết, tôi đặt các cấu hình môi trường ở đó chỉ để tập trung vào việc chạy mã cho những người mới sử dụng nút. js và thể hiện. Với khách hàng của tôi, tôi thường làm theo đề xuất của bạn. Điều đó nói rằng, cảm ơn vì đã chỉ ra điều này, lẽ ra tôi nên viết điều này trong bài báo như một lời cảnh báo. Trân trọng,

Marcos Henrique da Silva

Xin chào Raghav, cảm ơn

Marcos Henrique da Silva

Xin chào Noha, bạn có thể thử mocha (https. //mochajs. org/) và supertest (https. //github. com/visionmedia/supertest) Thông thường, tôi sử dụng kết hợp cả hai để thử nghiệm đơn vị cho các dự án của mình. Trân trọng,

Marcos Henrique da Silva

Chào loai, Giả sử bạn đã quen thuộc với terminal và dòng lệnh, thì tại thư mục gốc của dự án, vui lòng chạy lệnh 'npm start'. Nó sẽ khởi động máy chủ tại cổng 3600. Khi đã xong, bạn sẽ có thể sử dụng Postman, Insomnia hoặc ứng dụng khách khác mà bạn có thể đang sử dụng để có thể thực hiện lệnh gọi API được mô tả trong bài viết bằng cách sử dụng điểm cuối ban đầu là localhost. 3600/ (một ví dụ xem cách tôi đã thực hiện trong bài viết đăng lên localhost. 3600/users và thêm phần thân JSON với tất cả các trường ở đó). Hy vọng nó hoạt động cho bạn, Trân trọng

Stephen Lawal

Xin chào, hướng dẫn tốt, một số bước chính đã bị bỏ qua trong phần giải thích nhưng nếu bạn có kiến ​​thức cơ bản về express thì bạn có thể làm theo. Tuy nhiên, tôi đã sao chép repo ngay bây giờ và chèn người dùng bị hỏng. LoạiLỗi [ERR_INVALID_ARG_TYPE]. Đối số "dữ liệu" phải là một trong các loại chuỗi, TypedArray hoặc DataView. Loại đã nhận không xác định

Marcos Henrique da Silva

Xin chào Stephen, cảm ơn vì phản hồi. Tôi vừa sao chép một dự án mới từ git, bắt đầu mongod trên thiết bị đầu cuối của mình và tạo một bài đăng cho người dùng mà không gặp sự cố nào. Bạn đã tạo yêu cầu đăng bài lên localhost chưa. 3600/người dùng có phần thân ứng dụng/json với. { "họ". "Marcos", "Họ". "Silva", "thư điện tử". "các quan chức. henrique@toptal. com", "mật khẩu". "mypasshere" } sử dụng người đưa thư, tôi có yêu cầu mã này. ``` POST /người dùng HTTP/1. 1 máy chủ. máy chủ cục bộ. 3600 Loại nội dung. ứng dụng/json Tác nhân người dùng. Người đưa thưRuntime/7. 11. 0 Chấp nhận. */* Kiểm soát bộ đệm. Postman-Token không có bộ đệm. 06e9191b-8311-4f33-8244-95e9036f4c5d,1f683a36-69b0-4080-aab0-11b901d52cbb Máy chủ. máy chủ cục bộ. bánh quy 3600. liên kết. sid=s%3ARN9D8kQpPNVLvglAQ1DWXy4HId0Z2IkY. u8ZeA3RiyRrYCQR3lB%2Bqtpg7Uuse2t8FCwqAL%2F3aWSQ chấp nhận mã hóa. gzip, giảm độ dài nội dung. 107 kết nối. kiểm soát bộ nhớ cache liên tục. không có bộ đệm { "firstName". "Marcos", "Họ". "Silva", "thư điện tử". "các quan chức. henrique@toptal. com", "mật khẩu". "pass123" } ```

Stephen Lawal

Lỗi của tôi, tôi thực sự là người đã phạm sai lầm, tôi xin lỗi. nó hoạt động tốt bây giờ

Marcos Henrique da Silva

Đừng lo lắng, tôi rất vui vì nó đang hoạt động

Atul

"chúng ta cần tạo lược đồ trong /users/models/users. kiểu mẫu. js" Tôi ước nó được thực hiện dễ dàng hơn. Thư mục này chính xác ở đâu. Chúng tôi có giả sử tạo tệp này không người dùng javascript. kiểu mẫu. js hay cái gì?

Marcos Henrique da Silva

Xin chào Atul, cảm ơn vì tin nhắn. Sau khi tải xuống dự án tại liên kết git, bạn sẽ tìm thấy một thư mục có tên là người dùng chứa một thư mục có tên là mô hình và bên trong người dùng. kiểu mẫu. tập tin js. liên kết đến tập tin ở đây. https. //github. com/makinhs/rest-api-tutorial/blob/master/users/models/users. kiểu mẫu. js, tôi khuyên bạn nên tải xuống dự án git để theo dõi bài viết. Dự án đã có tất cả các tệp nguồn cần thiết. Chỉ cần đảm bảo đã cài đặt nút và mongodb trên máy của bạn. Trân trọng,

Vinicius Gati

Obrigado Marcos me ajudou pra caramba

Marcos Henrique da Silva

Fico feliz em saber que te ajudou. )

rani garcia

Xin chào, Cảm ơn bạn về hướng dẫn này, nhưng tôi gặp một chút vấn đề với việc làm mới mã thông báo, tôi luôn gặp lỗi Mã thông báo làm mới không hợp lệ, Bạn có thể giúp tôi tìm ra cách tôi có thể sử dụng /auth/refresh không?

rani garcia

Xin lỗi nhưng tôi chưa quen với NodeJS

Marcos Henrique da Silva

Xin chào, Bạn có thể vui lòng chia sẻ yêu cầu hoàn chỉnh của mình về lỗi mã thông báo làm mới không?

Rahul Shetty

Bài đăng này không dành cho người mới bắt đầu

Zangetsu Ichirin

Đúng vậy, theo cách đó bạn có thể đặt một cửa hậu và bất cứ thứ gì bạn muốn trong thư viện của mình. ') Mọi người nên sử dụng các phương pháp mã hóa của riêng họ, theo cách đó sẽ không có gì ngạc nhiên lớn vào ngày chúng tôi nhận ra 99% mật khẩu được băm đã bị hack vì một số thiên tài đã tìm thấy lỗ hổng trong thuật toán được sử dụng để băm chúng

Marcos Henrique da Silva

Xin chào Rahul, cảm ơn vì phản hồi. Thật không may, hơi khó để đưa tất cả thông tin cho người mới bắt đầu. Đối với các bài viết tiếp theo của tôi, tôi sẽ cố gắng hướng dẫn ít nhất là nơi mà một người mới bắt đầu nên tìm để bắt đầu học. Trân trọng,

Rahul Shetty

Tôi không có ý nói nó không hữu ích. Đó là một viên ngọc quý nhưng những người mới bắt đầu có thể cảm thấy hơi lạc lõng. Cảm ơn vì những nỗ lực bạn đã bỏ ra để tổng hợp bài đăng này. Sẽ háo hức chờ đợi bài viết tiếp theo của bạn. Ngoài ra, nếu bạn có thể, vui lòng cho chúng tôi biết đường dẫn đến nút học tập. js và các thư viện khen ngợi nút. js và đang được cộng đồng sử dụng rộng rãi. Ví dụ, tôi đã biết rằng hầu hết các nút. nhà phát triển js sử dụng bản thảo với nút. js

Kenneth Marshall

bài đăng tuyệt vời. Làm thế nào bạn sẽ xử lý tất cả các hoạt động REST cho một danh sách? . g. Tôi muốn nhận/xóa/vá người dùng cho userids. [12.134.532.600.765.890.900]

Marcos Henrique da Silva

Xin chào Kenneth, Nói chung, chúng ta có thể sử dụng các thao tác hàng loạt cho việc này. Đôi khi, rất khó để cố gắng trở thành người theo chủ nghĩa thuần túy 100% trong việc triển khai REST. Bạn nhất quán nhất có thể thì càng tốt. Ý tưởng chính là luôn nghĩ xem API của bạn sẽ dễ sử dụng và duy trì tính nhất quán như thế nào. Đối với tất cả các hoạt động hàng loạt, bạn có thể thêm mẫu Tiêu đề vào api của mình như. Hành động X. hàng loạt X-Action. đơn lẻ Khi bạn chuyển số lượng lớn, API của bạn sẽ xử lý yêu cầu dưới dạng Danh sách và khi nó nhận được một đơn lẻ, sau đó xử lý dưới dạng một tài nguyên. 1) Đối với phương thức get, bạn có thể thêm bộ lọc truy vấn nếu danh sách không đủ lớn để thêm dưới dạng truy vấn và bạn có thể triển khai nó theo nhiều cách. 1. 1) Ví dụ. truy cập /users?id=12,134,532,600,765,890,900 1. 2) Ví dụ. truy cập /users?id=12+134+532+600+765+890+900 1. 3) Ví dụ. truy cập /users?id=12. 134. 532. 600. 765. 890. 900 2) Để xóa, có thể khó. Một cách tiếp cận có thể phù hợp với kịch bản của bạn sẽ phụ thuộc vào thông tin người dùng của bạn. Ví dụ: nếu người dùng của bạn có một trường được gọi là 'isDeleted', thì bạn có thể sắp xếp để gửi một phương thức vá với Danh sách người dùng của mình. 2. 1) sử dụng PATCH cho/người dùng và gửi danh sách có tất cả thông tin người dùng và tất cả với isDeleted. đúng cờ 2. 2) Một cách tiếp cận khác có thể là sử dụng danh sách có trường op được gọi là 'xóa' và với url tài nguyên để xóa 2. 2. 2) Bản vá cho/tiêu đề người dùng. Hành động X. cơ thể số lượng lớn. [{ "op". "xóa", "đường dẫn". "/người dùng/12" },. {"op". "xóa", "đường dẫn". "/users/900" }, ] 3) Đối với cả PATCH và PUT, nếu bạn thêm giá trị số lượng lớn vào tiêu đề X-Action, thì bạn có thể xử lý gần giống như cách bạn thực hiện với một tài nguyên, nhưng xử lý . Tôi đã cố gắng làm cho nó ngắn gọn, nhưng đây là một chủ đề thậm chí có giá trị cho một bài báo mới. Tôi hy vọng rằng bạn có thể có ý tưởng chung về cách bắt đầu tiếp cận các hoạt động danh sách của mình. Trân trọng,

Jorge Nunes

Xin chào, Marcos Tôi không thể tạo người dùng. Mình dùng postman điền họ tên, email và pass nhưng màu đỏ. nội dung là {} trong dòng 18 người dùng. bộ điều khiển. js hãy băm = tiền điện tử. createHmac('sha512', muối). cập nhật (yêu cầu. thân thể. mật khẩu mở khóa). tiêu hóa ("cơ sở64"); . Đối số "dữ liệu" phải là một trong các loại chuỗi, Bộ đệm, TypedArray hoặc DataView. Đã nhận loại không xác định tại Hmac. cập nhật (nội bộ/tiền điện tử/băm. js. 69. 11) khi xuất khẩu. chèn (/người dùng/bộ điều khiển/người dùng. bộ điều khiển. js. 18. 50)

Saurabh Đặng

Này, Chỉ là một câu hỏi, tại sao và ở đâu bạn đặt mức cấp phép từ 1 đến 7?

Rodrigo Graca

có vẻ @zangetsuichirin. disqus cần tìm hiểu thêm một chút về bảo mật. Tôi khuyên bạn nên nghe. Bảo mật ngay bây giờ Podcast

Marcos Henrique da Silva

Xin chào Saurabh, cảm ơn vì đã hỏi. Khi bạn chèn một người dùng mới, mã sẽ đặt cấp độ quyền là 1. Bạn nên tự viết mã yêu cầu đến nơi thay đổi Cấp độ quyền. Ở góc độ quản trị viên, bạn nên thêm một điểm cuối mà chỉ quản trị viên mới có thể sử dụng để thay đổi cấp độ quyền của người dùng, chẳng hạn như đặt vào /users/. userId/permissionLevel/. cấp phép. Lý do tại sao những con số này chuyển đến toán tử Bitwise AND (&), về cơ bản cho phép bạn thêm một số lớp quyền đi từ 1, 2, 4,. 128,. và bật và người dùng có thể có sự kết hợp của các quyền này dưới dạng tổng của nó. Quyền 7 sẽ cho phép người dùng có 1 + 2 + 4 = 7. Trong trường hợp đó, bạn có thể xác định quy tắc của mình là 1. kế hoạch miễn phí 2. có thể chỉnh sửa một số thứ 4. có thể mời mọi người thì người dùng có 7 sẽ có tất cả gói miễn phí, có thể chỉnh sửa mọi thứ và mời mọi người và người dùng có 5 sẽ chỉ có thể chỉnh sửa mọi thứ và thuộc về gói miễn phí. Lời giải thích sâu sắc sẽ khá lớn để đặt nó ở đây nhưng tôi hy vọng rằng nó đã giúp bạn. Trân trọng,

Marcos Henrique da Silva

Xin chào Jorge, dòng 18 của người dùng. bộ điều khiển. js không thuộc về phương thức chèn. Phương thức tạo người dùng phải nằm trong khoảng từ dòng 4 đến 13 (https. //github. com/makinhs/rest-api-tutorial/blob/master/users/controllers/users. bộ điều khiển. js) Vui lòng đảm bảo rằng bạn đang thực hiện một yêu cầu dưới dạng POST đối với người dùng điền vào phần nội dung bằng FirstName, LastName, email và mật khẩu và đảm bảo rằng tiêu đề có application/json. Ngay cả sau đó, bạn vẫn sẽ gặp sự cố, vui lòng thêm yêu cầu hoàn chỉnh mà bạn đang thực hiện qua Postman dưới dạng câu trả lời tại đây. Trân trọng,

Roger Snowden

Tại sao bài viết này không có ngày?

Marcos Henrique da Silva

Xin chào Roger, cảm ơn vì nhận xét. Dự án và bài viết được xây dựng vào tháng 5 năm 2018. Rất tiếc, tôi không có câu trả lời thích hợp về lý do tại sao bài báo không có ngày tháng. Các phụ thuộc được cập nhật tại kho lưu trữ github và vẫn tốt để sử dụng các phiên bản nút mới hơn. Bạn có thể sử dụng các tính năng nhập từ ecma mới nhất nếu muốn. Vào thời điểm tôi thực hiện bài viết, tôi đã không quyết định thực hiện dự án trong TypeScript và tôi sẵn sàng tạo một bài viết mới và cập nhật bằng cách sử dụng các tiêu chuẩn mới nhất mà mọi người đang sử dụng cho các dự án back-end mới bằng NodeJS. Nếu bạn có bất cứ đề nghị hoặc câu hỏi xin vui lòng cho tôi biết. Cảm ơn trước,

Tobias Pa

làm thế nào chúng ta có thể phục vụ api này với ssl?

Marcos Henrique da Silva

Xin chào Tobias, điều đó sẽ phụ thuộc vào nơi bạn lưu trữ nó. Ví dụ: nếu bạn đang sử dụng Digital Ocean, bạn có thể cài đặt apache2, sau đó định cấu hình miền sẽ phân phát API, sau đó bạn có thể sử dụng công cụ miễn phí như Let's Encrypt để cài đặt chứng chỉ SSL. Nếu bạn đang cung cấp API tại aws, họ có thể cung cấp SSL cho API của bạn sau khi bạn định cấu hình miền. Hy vọng rằng thông tin này có thể tạo điểm khởi đầu tốt cho việc tìm kiếm của bạn, Trân trọng,

Tobias Pa

tôi lưu trữ trên máy chủ của riêng mình bằng apache và cho phép mã hóa. nhưng api không có phản hồi nếu tôi sử dụng https. với http nó hoạt động tốt chứng chỉ hoạt động rất tốt nếu tôi sử dụng tệp html bình thường. tôi nghĩ rằng nó phụ thuộc vào cổng phải không?

Marcos Henrique da Silva

Thông thường, bạn cần cho phép cổng 443 tại tường lửa của mình. Hãy thử điều đó và cho tôi biết nếu nó hoạt động. Sau khi bạn có thể định cấu hình api http của mình để tự động chuyển hướng đến https,

Saud Chougle

xin chào da silva, tôi thích hình ảnh bài đăng trên blog của bạn, tôi có thể sử dụng nó trong bài đăng của mình không

Terry Piercson

Xin chào Marcos, Cảm ơn bạn rất nhiều về hướng dẫn. Tôi đang gặp phải một số vấn đề, tuy nhiên. Tôi đã thiết lập dự án này bằng cách sử dụng docker chạy trên cổng 3600 - mã không bị ảnh hưởng. - Chức năng xóa của tôi đang trả về 401 trái phép bất kể tôi làm gì. Tất cả các chức năng khác hoạt động. Làm cách nào tôi có thể đi sâu vào nguyên nhân cốt lõi của vấn đề? . e. Tôi là John với quyền cấp 7 xóa Sarah mới tạo và trả về 401 trái phép. Tôi có bao gồm mã thông báo mang của John và thậm chí đã thử thay thế nó bằng của Sarah chỉ để kiểm tra nó. - Tôi nên ghi nhật ký lỗi ở đâu? . Tôi sẽ tìm nhật ký lỗi trong bảng điều khiển docker ở đâu?

Terry Piercson

Xin chào Marcos, Cảm ơn bạn rất nhiều. Bạn có thể làm sáng tỏ cách chúng tôi có thể sử dụng mã thông báo làm mới để duy trì các phiên của người dùng cho đến khi đăng xuất không?

Marcos Henrique da Silva

Xin chào Saud, những hình ảnh này là tài sản của Toptal, tôi không chắc rằng bạn có thể sử dụng chúng mà không có sự chấp nhận của họ. Vui lòng liên hệ trực tiếp với Toptal

Marcos Henrique da Silva

Xin chào Terry, tại ứng dụng giao diện người dùng của bạn, bạn có thể có một dịch vụ quản lý để gửi yêu cầu mã thông báo làm mới trong nền để nhận mã thông báo mới mà người dùng không thấy điều đó xảy ra. Cách bạn tạo dịch vụ này sẽ phụ thuộc vào ngăn xếp mà bạn đang sử dụng. Và logic có thể đi trong mỗi X phút để lấy một cái mới làm ví dụ. Trân trọng,

dave

Có vẻ như bạn phải biết nhiều về Node. js và MongoDB và Mongoose và Express để thực hiện công việc này. dường như còn thiếu rất nhiều keo và tôi mới chỉ tìm hiểu về Node. Có lẽ cái này dành cho các chuyên gia chưa xây dựng API

Talha Meer

Tôi muốn tạo apis công khai cho dự án của mình (như twitter, facebook, google cung cấp apis công khai). Bạn có thể hướng dẫn tôi làm thế nào để tôi có thể đạt được?

đồi jonathan

xin chào marcos, tôi đánh giá cao hướng dẫn này bây giờ hơi cũ nhưng tôi nghĩ dù sao thì tôi cũng sẽ thử. Sau khi cố gắng làm cho nó hoạt động bằng cách sử dụng phương pháp tiếp cận từng bước, tôi không gặp may mắn nên tôi quyết định lấy toàn bộ repo và xem liệu tôi có thể nhận được phản hồi hay không để xem xét kỹ thuật đảo ngược nó để tìm ra nguyên nhân . Tôi chạy chỉ mục nút. js và sau đó tạo một yêu cầu đăng với json thô cho người dùng trong hướng dẫn ở trên. url là http. //máy chủ cục bộ. 3600/người dùng. Yêu cầu trong người đưa thư bị treo và tôi không nhận được phản hồi. Nó có nghĩa đen là 'Đang gửi yêu cầu. ' và không làm gì cả. Dưới đây là yêu cầu http được lấy từ người đưa thư. POST/người dùng HTTP/1. 1 máy chủ. máy chủ cục bộ. 3600. Loại nội dung. ứng dụng/json { "tên đầu tiên". "Marcos", "Họ". "Silva", "thư điện tử". "các quan chức. henrique@toptal. com", "mật khẩu". "s3cr3tp4sswo4rd" } Bạn có biết vấn đề có thể là gì không?

Marcos Henrique da Silva

Xin chào Talha Meer, tôi sẽ sẵn lòng trợ giúp bất kỳ câu hỏi nào mà bạn có thể có

Marcos Henrique da Silva

Xin chào Dave, hướng dẫn này dành cho những người đã quen với những kiến ​​thức cơ bản về Node. JS muốn tăng tốc độ phát triển API bằng Express. JS Nếu bạn muốn chia sẻ tất cả những điểm còn thiếu cho người mới bắt đầu, tôi rất vui được cập nhật hoặc tạo một bài viết mới tập trung vào những điều cơ bản Trân trọng,

Marcos Henrique da Silva

Xin chào Jonathan Hill, các bước tôi đang làm để tái tạo những gì bạn đang viết. 1. bản sao git 2. npm cài đặt 3. docker-compose build 4. docker-soạn lên 5. mở người đưa thư 5. 1) Địa chỉ tới. máy chủ cục bộ. 3600/người dùng sử dụng POST làm phương thức 5. 1. 1) Thêm tiêu đề. Loại nội dung. ứng dụng/json 5. 2) cơ thể. { "họ". "Marcos", "Họ". "Silva", "thư điện tử". "các quan chức. henrique@toptal. com", "mật khẩu". "s3cr3tp4sswo4rd" } 5. 3) nhận được phản hồi. { "Tôi". "5e613d8bfa0a950011ae2ad5" } ``` curl --location --request POST 'localhost. 3600/người dùng' \ --header 'Loại nội dung. ứng dụng/json' \ --data-raw '{ "firstName". "Marcos", "Họ". "Silva", "thư điện tử". "các quan chức. henrique@toptal. com", "mật khẩu". "s3cr3tp4sswo4rd" }' ``` Vui lòng cho tôi biết nếu điều đó phù hợp với bạn. Ngoài ra, có một dự án github mới được cập nhật (2020) trong tài khoản github của tôi với Typescript mà bạn có thể muốn thử. https. //github. com/makinhs/expressjs-api-tutorial Trân trọng,

Jeff Davidson

ngày xuất bản của bài viết này xin vui lòng là gì?

dave

Bạn đã có thể làm điều đó mà không cần tôi chỉ ra

Marcos Henrique da Silva

Xin chào Jeff, nó được xuất bản vào giữa năm 2018. Mặc dù lý thuyết và các chủ đề ở đây không thay đổi nhiều, nhưng bạn có thể thấy mã được cập nhật bằng Bản mô tả và các phụ thuộc được cập nhật trên dự án github khác của tôi tại đây. https. //github. com/makinhs/expressjs-api-tutorial/ Trân trọng,

Jeff Davidson

Cảm ơn Marcos đã trả lời và cảm ơn vì hướng dẫn tuyệt vời

Marcos Henrique da Silva

Xin chào Sebastiano, cảm ơn vì nhận xét của bạn. Đó là một thách thức khi cố gắng tóm tắt một số chủ đề để đưa vào một bài viết hướng dẫn cách xây dựng Rest API bằng ExpressJS. Mongoose không được giải thích để tránh đưa thêm những phần 'khó hiểu' vào bài viết. Ý tưởng chính là git clone/fork dự án và chạy nó và theo dõi bài viết. Nếu bạn chạy project bằng docker thì lúc này bạn không cần quan tâm nhiều đến Mongoose. Ngoài ra, bạn có thể thay thế Mongoose bằng bất kỳ ORM/ODM hoặc SQL thuần nào khác nếu bạn muốn/cần. Đối với các hướng dẫn tiếp theo, tôi sẽ nghĩ về việc sử dụng một cuộn tròn để sao chép và dán để dễ dàng thực hiện quá trình kiểm tra trong khi đọc. Vào thời điểm tôi viết bài này, tốt nhất là không nên đưa vào văn bản thuần túy các yêu cầu sao chép và dán. Cảm ơn một lần nữa cho phản hồi của bạn, Trân trọng

Haoting Liu

không nên lắm, bài viết không bao giờ thực sự chia nhỏ từng khối mã và giải thích từng dòng một, khó hiểu

Marcos Henrique da Silva

Xin chào Haoting Liu, Cảm ơn bạn đã trả lời, Bài viết này nhằm vào các nhà phát triển đã có một chút kiến ​​thức trước về NodeJS và để duy trì càng ngắn càng tốt, chúng tôi đã tránh viết quá nhiều chi tiết về mã. Chúng tôi sẽ cố gắng cải thiện trong những lần tiếp theo. Trân trọng,

Sudarshan Kj

Chào Marcos. Tôi phải nói rằng bài viết này được viết rất tốt và đúng trọng tâm. Tuy nhiên, bạn có phiền khi giải thích cách hoạt động của mã thông báo làm mới không vì mặc dù có một tuyến đường được xác định cho 'auth/refresh', nhưng nó không sử dụng chức năng 'refresh_token' được xác định trong 'ủy quyền'. bộ điều khiển. js' -kJ

Marcos Henrique da Silva

Xin chào Sudarshan, xin lỗi vì trả lời muộn. Khi bạn chuyển refresh_token qua phần thân tại mã thông báo xác thực/làm mới, có 2 phần mềm trung gian sử dụng nó. tại verifyRefreshBodyField, tôi chỉ cần kiểm tra xem bạn có sử dụng refresh_token làm trường nội dung hay không. tại validRefreshNeeded. chúng tôi sử dụng biến ở đây. hãy để b = Bộ đệm mới (yêu cầu. thân thể. refresh_token, 'base64'); . hãy refresh_token = b. toString(); . createHmac('sha512', req. jwt. refreshKey). cập nhật (yêu cầu. jwt. userId + bí mật). tiêu hóa ("cơ sở64"); . Tôi cũng khuyên bạn nên thử sử dụng phương pháp hợp nhất như http. //www. hộ chiếu. org/packages/passport-jwt/ sẽ thực hiện tất cả những gì tôi đã viết trong thư viện của họ mà bạn không cần lo lắng về điều đó. Chúc mừng,

Sudarshan Kj

Cảm ơn câu trả lời của bạn Marcos

Sanjay Yadav

Bài đăng tuyệt vời về bảo mật API. Vui lòng chia sẻ thêm về cách bảo mật jwt trong giao diện người dùng phản ứng

vipul

ứng dụng. bản vá ('/người dùng/. Id người dùng', [ Phần mềm trung gian xác thực. hợp lệJWTNeeded, PermissionMiddleware. minimumPermissionLevelRequired(MIỄN PHÍ), PermissionMiddleware. onlySameUserOrAdminCanDoThisAction, UsersController. patchById ]); . Tôi mới thể hiện js. Thưa ông, ông có thể nói rõ hơn không, tôi đang hình dung đoạn mã trên cho ứng dụng này. bản vá ('/người dùng/. user Id', fun(req, res, next) { Phần mềm trung gian xác thực. hợp lệJWTNeeded, PermissionMiddleware. minimumPermissionLevelRequired(MIỄN PHÍ), PermissionMiddleware. onlySameUserOrAdminCanDoThisAction, UsersController. patchById } );

Marcos Henrique da Silva

Xin chào vipul, bên trong mảng [] bạn nên sử dụng hàm nhận yêu cầu, phản hồi và tiếp theo. Trong trường hợp này, cho đến khi bạn đến patchById, bạn nên gọi hàm tiếp theo trong hàm đã truyền trước đó trong trường hợp hàm đó phù hợp với điều kiện của bạn. Cách bạn viết không thể hoạt động do các vấn đề về cú pháp. Cách chính xác phải là ứng dụng. bản vá ('/người dùng/. Id người dùng', [ Phần mềm trung gian xác thực. hợp lệJWTNeeded, PermissionMiddleware. minimumPermissionLevelRequired(MIỄN PHÍ), PermissionMiddleware. onlySameUserOrAdminCanDoThisAction, UsersController. patchById ] ); . ứng dụng. bản vá ('/người dùng/. Id người dùng', Phần mềm trung gian xác thực. hợp lệJWTNeeded, PermissionMiddleware. minimumPermissionLevelRequired(MIỄN PHÍ), PermissionMiddleware. onlySameUserOrAdminCanDoThisAction, UsersController. patchById ); . Hy vọng nó trở nên dễ hiểu hơn, Trân trọng,

Marcos Henrique da Silva

Xin chào Sanjay, tôi đã viết một bài giải thích ngắn về jwt và phản ứng ở đây. https. //Trung bình. com/@makinhs/configure-a-react-app-to-handle-authentication-without-redux-with-hooks-4424e9c30d73 Hy vọng nó sẽ giúp ích cho trường hợp của bạn

siok meng

Xin chào, tại sao list và removeById bạn trả về Promise, còn các phương thức khác chỉ trả về trực tiếp?

Andrey Dergachev

Rất thẳng và đẹp. một mẹo nhỏ. xuất giao diện CRUD { danh sách. (giới hạn. số, trang. số) => Hứa, tạo. (nguồn. T) => Lời hứa, updateById. ( nguồn. T) => Lời hứa, readById. (ID tài nguyên. TKey) => Lời hứa, xóaById. (ID tài nguyên. TKey) => Lời hứa, // patchById. (ID tài nguyên. bất kỳ) => Lời hứa, }

Chúng tôi có thể sử dụng API REST trong JavaScript không?

API REST là một cách dễ dàng truy cập các dịch vụ web . Khi API RESTful được gọi, máy chủ sẽ chuyển cho máy khách một biểu diễn trạng thái của tài nguyên được yêu cầu.

Làm cách nào để gọi API dịch vụ web REST từ JavaScript?

Chúng ta sẽ tạo một biến yêu cầu và gán một đối tượng XMLHttpRequest mới cho nó. Sau đó, chúng tôi sẽ mở một kết nối mới bằng phương thức open() - trong các đối số, chúng tôi sẽ chỉ định loại yêu cầu là GET cũng như URL của điểm cuối API. Yêu cầu hoàn thành và chúng tôi có thể truy cập dữ liệu bên trong hàm onload

Làm cách nào để gọi API bằng JavaScript?

Gọi API web bằng JavaScript .
Định cấu hình ứng dụng để phân phát các tệp tĩnh và bật ánh xạ tệp mặc định. .
Tạo một thư mục wwwroot trong thư mục gốc của dự án
Tạo một thư mục css bên trong thư mục wwwroot
Tạo một thư mục js bên trong thư mục wwwroot
Thêm một tệp HTML có tên là chỉ mục. html vào thư mục wwwroot

API REST trong JS là gì?

API REST là giao diện lập trình ứng dụng tuân thủ các ràng buộc của kiểu kiến ​​trúc REST và cho phép tương tác với các dịch vụ web RESTful . Các mạng được kết nối với nhau tạo nên trang web. Dịch vụ web là một tập hợp các giao thức và tiêu chuẩn mở được sử dụng để trao đổi dữ liệu giữa các ứng dụng máy khách-máy chủ.