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 Show
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
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 RESTAPI 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
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à 2Tài nguyên của chúng tôi sẽ có cấu trúc cơ bản sau
Và chúng ta sẽ tạo các thao tác sau cho tài nguyên đó
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à 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 APITrướ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 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ã jsGhi 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 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
Bây giờ, hãy chạy 35 (hoặc 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ùngChú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 37 1Khi 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 2Sau đó, 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 38
Điều này được kéo vào Express của chúng tôi. js trong tệp chính 39. Đối tượng 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 61
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 ( 62) và gửi yêu cầu 7 tới 30 với một số dữ liệu JSON 3Có 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 3Tạ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. 65. Chúng ta cũng cần thêm phương thức 66 vào mô hình trong 67 6Bâ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 68Đầu tiên, chúng tôi tạo một Express. tuyến đường js trong 69 0Sau đó, chúng tôi tạo bộ điều khiển trong 61 2Và cuối cùng, thêm phương thức 01 vào mô hình trong 37 5Câu trả lời sẽ giống như thế này 20Lư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à 8, mà chúng ta sẽ sử dụng để xử lý các quyền của người dùng sau nàyLặ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 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à 0 đến 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 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 21Theo 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 08 vào mô hình 22Bộ điều khiển sau sẽ triển khai danh sách người dùng dưới dạng 8 tại 20 23Phương pháp mô hình tương ứng sẽ là 24Phản hồi danh sách kết quả sẽ có cấu trúc sau 25Và phần cuối cùng được thực hiện là 1 tại 34Bộ điều khiển của chúng tôi để xóa sẽ là 26Tươ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 27Bâ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ựcTrước khi chúng tôi có thể bảo mật mô-đun 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ậpTrướ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 7 đối với tài nguyên 25. Nội dung yêu cầu sẽ chứa email và mật khẩu của người dùng 28Trướ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 26 29Làm xong việc đó, chúng ta có thể chuyển sang bộ điều khiển và tạo JWT 0Mặ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 27 1Phản hồi sẽ chứa JWT được tạo trong trường accessToken 2Sau khi tạo mã thông báo, chúng tôi có thể sử dụng nó bên trong tiêu đề 28 bằng cách sử dụng biểu mẫu 29Tạ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 2. Đây là những tình huống mà chúng ta sẽ cần phải xử lý
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 51 có thể đơn giản như 3Chúng tôi sẽ sử dụng mã lỗi HTTP để xử lý lỗi yêu cầu
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 4Phầ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 52 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 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 theoAPI sẽ phản hồi với ID người dùng Bây giờ chúng ta có thể tạo JWT bằng cách sử dụng điểm cuối 54Chú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 Lấy 55, đặt trước nó bằng 56 (nhớ khoảng trắng) và thêm nó vào tiêu đề yêu cầu bên dưới 28Nế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ừ 34Như đã đề 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 Bất ngờ. Chúng tôi nhận được phản hồi 403 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 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) 6Bâ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 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 0 với một số trường đến điểm cuối 34 của chúng tôiChú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 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— 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 28 của mìnhGửi yêu cầu 1 tới 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 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 theoVớ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
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
Thẻ JavaScript nhanh. jsRESTNode. jsNgườ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
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ủ. |