Tổng Quan về API Web
- 02-07-2024
- Toanngo92
- 0 Comments
Sự gia tăng sử dụng điện thoại thông minh và các thiết bị tương tự để truy cập các dịch vụ qua web đòi hỏi một công nghệ giúp đơn giản hóa việc cung cấp dịch vụ cho nhiều loại khách hàng khác nhau. ASP.NET Web API là một trong những công nghệ như vậy được cung cấp bởi Microsoft, cho phép các khách hàng tạo các dịch vụ Web nhắm đến nhiều khách hàng khác nhau. Sử dụng ASP.NET Web API, các yêu cầu của khách hàng có thể được xử lý và các phản hồi có thể được gửi lại bằng các loại nội dung như JavaScript Object Notation (JSON) hoặc XML.
ASP.NET Web API là một khung mạnh mẽ được Microsoft cung cấp, cho phép tạo các dịch vụ HTTP. Các dịch vụ này dễ dàng truy cập bởi một loạt các khách hàng, bao gồm các trình duyệt web và thiết bị di động.
ASP.NET Web API lý tưởng để xây dựng các ứng dụng RESTful trên nền tảng .NET, hỗ trợ phản hồi ở các định dạng JSON và XML, đáp ứng các yêu cầu đa dạng của khách hàng. Ngoài chức năng cơ bản, ASP.NET Web API còn cung cấp các tính năng mạnh mẽ như các cơ chế xác thực và ủy quyền, bao gồm OAuth và xác thực dựa trên token, để bảo vệ các ứng dụng web một cách hiệu quả. Nó sử dụng một hệ thống định tuyến linh hoạt để hướng các yêu cầu HTTP đến các bộ điều khiển thích hợp, nâng cao khả năng sử dụng và bảo trì của API.
Hơn nữa, khung này hỗ trợ các bộ lọc hành động để triển khai các mối quan tâm cắt ngang như ghi nhật ký và xử lý ngoại lệ, và hỗ trợ tiêm phụ thuộc để tạo mã không liên kết và dễ thử nghiệm. Với hỗ trợ tích hợp cho đàm phán nội dung, ASP.NET Web API đảm bảo rằng các dịch vụ có thể cung cấp dữ liệu ở định dạng phù hợp nhất cho mỗi khách hàng, mở rộng thêm tính linh hoạt của nó.
Sự tích hợp với ASP.NET Core đánh dấu một bước tiến, đơn giản hóa việc phát triển các ứng dụng và dịch vụ web trong một khung thống nhất. Tập hợp tính năng toàn diện này làm cho ASP.NET Web API trở thành lựa chọn ưa thích của các nhà phát triển nhằm cung cấp các dịch vụ web chất lượng cao, có khả năng mở rộng và bảo mật.
Mục lục
Sự Phát Triển của API Web
Quy tắc cơ bản nhất cho sự phát triển của một API là hành vi có thể quan sát từ bên ngoài của API (từ góc nhìn của khách hàng) không thể bị thay đổi sau khi API đã được công bố. Bất kỳ thay đổi nhỏ nào của API cũng có thể làm hỏng một số khách hàng đang sử dụng API. Không thể cập nhật mỗi người dùng hoặc ít nhất là không thực tế vì họ thuộc quyền kiểm soát của các chủ sở hữu khác nhau. Do đó, tuổi thọ và tính ổn định là những khía cạnh quan trọng của các API đã được công bố.
Hạn chế áp đặt bởi quy tắc này có thể nghe có vẻ khắt khe và thậm chí là trái ngược vì API thường phát triển sử dụng phương pháp phát triển Agile. Các phương pháp Agile dựa trên các vòng lặp phản hồi và khái niệm về nhiều thay đổi gia tăng trong phần mềm. Phương pháp Agile vẫn áp dụng cho các API mới hoặc chưa được công bố. Trước khi công bố API, bất kỳ thay đổi nào cũng có thể được thực hiện một cách linh hoạt. Khi API đã được công bố, chúng trở nên có sẵn cho người dùng và phải giả định rằng người dùng xây dựng các ứng dụng dựa vào các API. Các API đã công bố không thể được thay đổi một cách linh hoạt. Ít nhất, API cần phải duy trì khả năng tương thích ngược và tiến, để khách hàng cũ không bị hỏng và khách hàng mới có thể sử dụng các tính năng mới và cải tiến.
ASP.NET Web API
Các thuộc tính của Model View Controller (MVC) bao gồm định tuyến, bộ điều khiển, bộ lọc, kết quả hành động, bộ liên kết mô hình, Inversion of Container (IOC), và tiêm phụ thuộc là một phần của ASP.NET Web API. Mặc dù được coi là tương tự như ASP.NET MVC, nó được xem là một phần của nền tảng ASP.NET cốt lõi và không phải là khung MVC.
Hình bên dưới mô tả khung của ASP.NET Web API.
Các Tính Năng Quan Trọng của ASP.NET Web API:
- Mô Hình Lập Trình Đơn Giản: Cho phép truy cập và cập nhật các yêu cầu và phản hồi HTTP một cách dễ dàng trong một ứng dụng ASP.NET Web API. Trong một ứng dụng ASP.NET Web API, mô hình lập trình tương tự được sử dụng trên máy chủ cũng như trên khách hàng. Khách hàng có thể là bất kỳ ứng dụng .NET nào.
- Đàm Phán Nội Dung: Cho phép khách hàng và máy chủ đàm phán định dạng dữ liệu mà dịch vụ trả về dưới dạng phản hồi. Mặc định, ASP.NET Web API hỗ trợ các định dạng JSON, XML, và URL-encoded. Nó cũng cung cấp tính linh hoạt để mở rộng định dạng dữ liệu mặc định bằng cách thêm các định dạng tùy chỉnh hoặc thay thế chiến lược đàm phán mặc định bằng một chiến lược tùy chỉnh.
- Định Tuyến Yêu Cầu: Cung cấp một mô-đun định tuyến chịu trách nhiệm ánh xạ các URL yêu cầu đến hành động của bộ điều khiển cụ thể. Sử dụng mô-đun định tuyến, các tuyến tùy chỉnh có thể được định nghĩa tại một vị trí trung tâm mà không cần các cấu hình bổ sung.
Loại Yêu Cầu và Phản Hồi
Yêu Cầu HTTP
Yêu cầu HTTP được sử dụng để giao tiếp qua Web. Khi người dùng nhập một URL vào thanh địa chỉ của trình duyệt, một yêu cầu HTTP được gửi đến một ứng dụng đang chạy trên máy chủ được đại diện bởi URL đó.
Ứng dụng xử lý yêu cầu và trả về một phản hồi HTTP. Trình duyệt, sau khi nhận được phản hồi, hiển thị phản hồi đó cho người dùng. HTTP cung cấp các phương thức yêu cầu khác nhau dựa trên loại thao tác mà yêu cầu yêu cầu. Bốn phương thức HTTP cơ bản là như sau:
- GET: Phương thức GET yêu cầu máy chủ truy xuất một tài nguyên.
- POST: Phương thức POST yêu cầu máy chủ xử lý dữ liệu chứa trong yêu cầu.
- PUT: Phương thức PUT yêu cầu máy chủ tạo hoặc cập nhật dữ liệu chứa trong yêu cầu.
- DELETE: Phương thức DELETE yêu cầu máy chủ xóa một tài nguyên.
Các tiêu đề yêu cầu HTTP chứa các thông tin sau đây:
- Host: Chỉ định tên miền của ứng dụng mà tài nguyên đang được truy cập.
- Accept: Chỉ định loại nội dung, còn được gọi là kiểu MIME (Multipurpose Internet Mail Extensions), mà yêu cầu mong đợi như là phản hồi.
- Accept-Language: Yêu cầu máy chủ sử dụng ngôn ngữ chỉ định để tạo hoặc cập nhật một yêu cầu.
- Connection: Xác định liệu máy chủ có nên sử dụng cùng một kết nối (giá trị keep-alive chỉ ra điều này) cho giao tiếp HTTP thay vì tạo một kết nối mới.
- Keep-Alive: Chỉ định khoảng thời gian theo giây mà máy chủ phải sử dụng cùng một kết nối để giao tiếp HTTP.
Phản hồi HTTP
Khi máy chủ nhận được yêu cầu HTTP, nó gửi lại một phản hồi HTTP. Phản hồi này có thể là kết quả của tài nguyên được yêu cầu hoặc là một mã trạng thái HTTP để chỉ ra rằng tài nguyên được yêu cầu không có sẵn.
Tương tự như yêu cầu HTTP, phản hồi HTTP bao gồm các tiêu đề phản hồi và một phần thân phản hồi.
Phản hồi HTTP chỉ định mã trạng thái phản hồi HTTP cùng với các tiêu đề phản hồi HTTP chính sau đây:
Triển khai Web API
Dưới đây là các bước để tạo một ứng dụng Web API bằng Microsoft Visual Studio 2022:
- Tạo một dự án mới như được hiển thị trong Hình bên dưới.
2. Tìm kiếm ASP.NET Core. Sau khi chọn mẫu ASP.NET Core Web API, nhấp vào Tiếp theo, như trong Hình bên dưới.
3. Thêm tên dự án và vị trí vào các hộp văn bản như trong Hình tiếp theo.
Một dự án API được tạo thành công. Cấu trúc dự án được tạo trong Solution Explorer như trong Hình bên dưới.
4. Chạy dự án API này mà không thực hiện bất kỳ sửa đổi nào đối với các tệp được tạo tự động trong dự án. Hình tiếp theo cho thấy kết quả đầu ra trong trình duyệt.
Kết quả của API Thời tiết được hiển thị trên Swagger, một công cụ phần mềm mã nguồn mở để thiết kế, xây dựng và sử dụng các API Web RESTful.
Các bước sau sẽ giải thích cách tạo một Web API cho phương thức GET HTTP:
Bước 1: Tạo một thư viện lớp .NET mới bằng cách nhấp chuột phải vào giải pháp trong Khám phá giải pháp và chọn Thêm → Dự án mới gọi là Sample.Data.
Bước 2: Thêm ba thư mục: Models, Interfaces, và Repository trong thư viện lớp Sample.Data. Tham khảo Hình bên dưới.
Bước 3: Tạo một lớp Model trong thư mục Model được gọi là Customer. Xem đoạn mã dưới đây.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sample.Data.Model
{
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
}
Bước 4: Trong thư mục Interface, tạo một interface được gọi là ICustomer. Xem đoạn mã dưới đây.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Sample.Data.Model;
namespace Sample.Data.Interface
{
internal interface ICustomer
{
List<Customer> GetAllCustomer();
Customer GetCustomer(int id);
}
}
Bước 5: Trong thư mục Repository
, tạo một lớp được gọi là CustomerRepo
và triển khai interface ICustomer
trong đó như được hiển thị trong đoạn mã bên dưới. Lớp này sẽ tương tác với cơ sở dữ liệu.
using Sample.Data.Interface;
using Sample.Data.Model;
using System.Collections.Generic;
using System.Linq;
namespace Sample.Data.Repository
{
public class CustomerRepo : ICustomer
{
List<Customer> lisCustomers = new List<Customer>
{
new Customer { CustomerId = 1, FirstName = "TênKháchHàng1", LastName = "HọKháchHàng1", Address = "Austin" },
new Customer { CustomerId = 2, FirstName = "TênKháchHàng2", LastName = "HọKháchHàng2", Address = "Austin" },
new Customer { CustomerId = 3, FirstName = "TênKháchHàng3", LastName = "HọKháchHàng3", Address = "Austin" },
new Customer { CustomerId = 4, FirstName = "TênKháchHàng4", LastName = "HọKháchHàng4", Address = "Austin" },
new Customer { CustomerId = 5, FirstName = "TênKháchHàng5", LastName = "HọKháchHàng5", Address = "Austin" }
};
public List<Customer> GetAllCustomer()
{
return lisCustomers;
}
public Customer GetCustomer(int id)
{
return lisCustomers.FirstOrDefault(x => x.CustomerId == id);
}
}
}
Ở đây, đoạn mã có dữ liệu giả mạo dưới dạng FirstNamel
, LastNamel
và các thông tin tương tự. Trong một ví dụ thực tế, bạn sẽ thay thế chúng bằng các tên khách hàng thực tế.
Bước 6: Tạo một controller trong thư mục controller có tên là CustomerController
. Thêm một controller mới bằng cách nhấp chuột phải vào thư mục controller như hình bên dưới. Đặt tên như được hiển thị trong hình tiếp theo.
Bước 7: Nhấp chuột phải vào API mẫu – Phụ thuộc và thêm tham chiếu dự án như trong Hình bên dưới.
Bước 8: Thực thi Dự án API khách hàng và màn hình như Hình tiếp theo sẽ xuất hiện.
Bước 9: Nhấp vào nút NHẬN ở bên trái hộp api/Khách hàng như trong Hình bên dưới. Kết quả sẽ như trong Hình tiếp theo.
Tương tự, Web API có thể được tạo ra cho các phương thức HTTP POST, PUT và DELETE.
Sử dụng Công cụ Thứ Ba để Kiểm Tra Web API
Khi Web API đã được phát triển, chúng được kiểm tra bằng các công cụ thứ ba. Trong số các công cụ này, Postman là một trong những công cụ tốt nhất để kiểm tra API.
Để tải ứng dụng Postman, sử dụng liên kết sau: https://www.getpostman.com/apps
Sau khi tải xuống và cài đặt, mở Postman. Các bước sau mô tả cách kiểm tra các API:
Bước 1: Sao chép địa chỉ URL của Web API sử dụng phương thức HTTP Get (ví dụ: https://localhost:7207/swagger/index.html) từ trình duyệt và dán vào Tab URL của Postman như hình bên dưới.
Bước 2: Kiểm tra phương thức POST để tạo vùng. Để thực hiện việc này, hãy sao chép phương thức POST và dán vào URL của Người đưa thư hoặc chỉnh sửa tiêu đề. Thay đổi yêu cầu HTTP thành POST trong phần nội dung của yêu cầu. Dữ liệu JSON phải được chuyển dưới dạng nội dung thô để tạo vùng. Các chi tiết được thể hiện trong hình bên dưới.
Bước 3: Sau khi đã thiết lập xong tất cả thông tin, hãy nhấp vào b. Việc này sẽ tạo ra khách hàng và hiển thị thông báo Thành công.
Bước 4: Để kiểm tra xem bản ghi đã được tạo hay chưa, hãy sử dụng phương thức Get để gọi. Bên trái cửa sổ hiển thị lịch sử các cuộc gọi gần đây.
Đăng Hosting Web API trong Microsoft Azure Web App
Nếu các nhà phát triển muốn phát hành dự án Web của họ một cách nhanh nhất, họ nên xem xét sử dụng Dịch vụ Ứng dụng Azure (Azure App Service). Dịch vụ lưu trữ này đáng tin cậy và có thể mở rộng và tự sửa chữa. Một nhóm tài nguyên được tạo khi ứng dụng ASP.NET Web đầu tiên sử dụng dịch vụ này hoạt động tốt. Nhóm này bao gồm một kế hoạch dịch vụ, một ứng dụng Web Azure và ứng dụng đã được sử dụng.
Các bước để xuất bản ứng dụng Web API lên Dịch vụ Ứng dụng Azure như sau:
Bước 1: Giả sử rằng một ứng dụng StudentServices đã được tạo, mở nó trong Visual Studio 2022. Nhấp chuột phải vào dự án StudentServices và chọn Publish từ menu xuất hiện. Điều này sẽ đưa bạn đến trang hồ sơ cho việc Xuất bản.
Bước 2: Vì đã có một hồ sơ xuất bản, nên tạo một hồ sơ mới cho việc xuất bản Ứng dụng Web. Các hồ sơ xuất bản có thể được nhìn thấy trong Hình bên dưới. Để tạo một hồ sơ, nhấp vào liên kết có tên New Profile.
Bước 3: Để tạo một Ứng dụng Web Azure, chọn Dịch vụ Ứng dụng từ menu ngữ cảnh cho tùy chọn Publish. Đảm bảo chọn tùy chọn ‘New‘. Hình bên dưới cho thấy các lựa chọn cho Ứng dụng Web.
Bước 4: Trong cửa sổ tiếp theo có tên là ‘Tạo dịch vụ ứng dụng’, hãy chọn Đã có tài khoản? Đăng nhập. Đăng nhập bằng tài khoản Azure của bạn và Tài khoản sẽ xuất hiện ở góc trên bên phải. Chọn tài khoản từ menu thả xuống bên cạnh Tài khoản. Điều này sẽ tự động tạo một ứng dụng Web với tên bạn chọn cho mình. Hình bên dưới minh họa cách thay đổi tên của ứng dụng.
Bước 5: Chọn Create. Điều này sẽ tạo hồ sơ Xuất bản và tự động tạo Ứng dụng Web và Web API. Sau khi thao tác xuất bản hoàn tất, ứng dụng Web API sẽ tự động mở trong trình duyệt mặc định của bạn. Địa chỉ là http://studentservicesazureapp.azurewebsites.net.
Bước 6: Bạn có thể kiểm tra API bằng ứng dụng Postman.
Định tuyến trong Web API
Các thủ tục định tuyến của ASP.NET MVC tương tự như của Web API. Trong khi phương thức HTTP được sử dụng trong Web API, phương thức URI được sử dụng trong ASP.NET MVC để lựa chọn một hành động. Web API chuyển tiếp một yêu cầu HTTP đến một phương thức hành động cụ thể trên một bộ điều khiển.
Định tuyến mặc định bằng Bảng định tuyến
Một bộ điều khiển là một loại lớp được tìm thấy trong ASP.NET Web API, có thể quản lý các yêu cầu HTTP. Các phương thức công khai của các bộ điều khiển được gọi là phương thức hành động hoặc hành động. Trong khuôn khổ của Web API, khi một yêu cầu đến, nó được định tuyến đến một hành động. Framework sử dụng một bảng định tuyến để quyết định hành động nào cần phải được gọi. Một dự án Visual Studio có một mẫu cho Web API tạo một định tuyến mặc định.
Mã cho điều này được miêu tả trong đoạn code bên dưới.
public static void Register(HttpConfiguration config)
{
// Cấu hình và dịch vụ Web API
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Con đường được đề cập trong đoạn mã trên là một phần của tệp WebApiConfig.cs,
nằm trong thư mục App_Start
như được hiển thị trong Hình bên dưới.
Điều này giả định rằng đã có một dự án có tên StudentServices
.
Mỗi mục trong bảng định tuyến đều chứa một mẫu đường dẫn nhúng trong đó. Đối với Web API, mẫu mặc định là ‘api/{controller}/{id}’. Thuật ngữ ‘api’ đề cập đến đoạn đường dẫn thực tế trong khi (controller) và (id) là các biến đổi chỗ.
Như đã thảo luận, khi một yêu cầu HTTP đến, URI của nó được so sánh với các mẫu đường dẫn của bảng định tuyến. Nếu so sánh thất bại, sẽ hiển thị lỗi 404. Ví dụ, các URI sau so sánh với định dạng ‘api/{controller}/{id}’ như được định nghĩa trong các định tuyến mặc định trong đoạn mã bên dưới:
/students Trả về danh sách sinh viên
/api/students/1 Trả về thông tin sinh viên có Student id 1
Có hai loại định tuyến được hỗ trợ bởi Web API:
- Định tuyến dựa trên quy ước
- Định tuyến thuộc tính
Định tuyến Dựa trên Quy ước
Mẫu đường dẫn được sử dụng bởi Web API để xác định controller và phương thức hành động để thực thi thay vì các tệp vật lý cụ thể. Ít nhất một mẫu đường dẫn phải được thêm vào bảng định tuyến để xử lý các yêu cầu HTTP khác nhau. Sử dụng mẫu định tuyến mặc định, Web API chọn một hành động bằng cách sử dụng một phương thức HTTP như được hiển thị trong đoạn mã bên dưới.
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Định tuyến dựa trên Thuộc tính (Attribute Routing):
Định tuyến dựa trên thuộc tính sử dụng thuộc tính [Route[]]
để xác định các đường dẫn. Định tuyến dựa trên thuộc tính cung cấp tính linh hoạt cho các URI được sử dụng trong Web API 2. Như được thể hiện trong Đoạn mã 6, mô tả các cấu trúc phân cấp của tài nguyên là một ví dụ về việc tạo các URI.
Định tuyến dựa trên thuộc tính cho phép bạn kiểm soát nhiều hơn đối với các URI trong Web API của bạn. Ví dụ, bạn có thể dễ dàng tạo các URI mô tả các cấu trúc phân cấp của tài nguyên.
[Route("students/{studentId}/marks")]
public IEnumerable<Student> GetOrdersByStudent(int studentId)
{
// Implement your logic here
}
Triển khai Hoạt động Cơ sở dữ liệu bằng Web API
Triển khai các phương thức HTTP GET (theo id), PUT và DELETE được giải thích chi tiết như sau:
Bước 1: Lấy thông tin sinh viên theo Id. Đoạn mã bên dưới đại diện cho phương thức GET theo Id.
[HttpGet]
[Route("api/Student/GetById/{id}")]
public IHttpActionResult GetById(int id)
{
var student = _context.Students.SingleOrDefault(e => e.StudentId == id);
return Ok(student);
}
Bước 2: Triển khai phương thức Sửa đổi (Edit). Để làm điều này, đầu tiên, tạo một lớp Model mới trong thư mục Models cho mục đích chỉnh sửa. Đặt tên là EditStudentModel
. Thêm các thuộc tính và các thuộc tính xác thực như được hiển thị trong Đoạn mã bên dưới.
using System;
using System.ComponentModel.DataAnnotations;
namespace StudentServices.Models
{
public class EditStudentModel
{
[Required(ErrorMessage = "StudentId Is required")]
[Display(Name = "Student Id")]
public int StudentId { get; set; }
[Required(ErrorMessage = "Student Name is required")]
[Display(Name = "Student Name")]
public string StudentName { get; set; }
[Required(ErrorMessage = "Student Email is required")]
[Display(Name = "Student Email")]
public string StudentEmail { get; set; }
[Display(Name = "Date of Join")]
public DateTime? StudentJoinDate { get; set; }
}
}
Bước 3: Thêm một phương thức mới trong Controller Student
có tên là Modify()
. Thêm mã trong Đoạn mã bên dưới để triển khai phương thức sửa đổi. Lưu ý rằng phương thức Modify()
được đánh dấu là phương thức HTTP PUT.
[HttpPut]
public IHttpActionResult Modify(EditStudentModel studentModel)
{
var student = new Student()
{
StudentId = studentModel.StudentId,
StudentName = studentModel.StudentName,
StudentEmail = studentModel.StudentEmail,
StudentJoinDate = studentModel.StudentJoinDate
};
context.Entry(student).State = EntityState.Modified;
context.SaveChanges();
return Ok("Success");
}
Bước 4: Thêm các đoạn mã trong Đoạn mã bên dưới để triển khai phương thức Xóa.
[HttpDelete]
public IHttpActionResult Delete(int id)
{
var student = _context.Students.SingleOrDefault(e => e.StudentId == id);
context.Students.Remove(student ?? throw new InvalidOperationException());
_context.SaveChanges();
return Ok("Success");
}
Bước 5: Sử dụng Postman để kiểm thử từng phương thức HTTP. Bảng 7.1 mô tả cách thực hiện từng phương thức HTTP.
Phương thức HTTP | Đường dẫn URI | Hành động | Tham số/Thân thể |
POST | api/Student | Create() | Đối tượng JSON Student là thân thể |
GET | api/Student | GetAll() | Không có |
GET | api/Student/1 | GetById | 1 |
PUT | api/Student | Modify() | Đối tượng JSON Student là thân thể |
DELETE | api/Student/1 | Delete() | 1 |
Triển khai Identity cho Xác thực
Khi đến với các ứng dụng cấp doanh nghiệp, một mặt mà yêu cầu sự quan tâm hàng đầu là bảo mật. Bảo mật được coi là vô cùng quan trọng khi tiết lộ dữ liệu kinh doanh hoặc quy trình qua các dịch vụ khác.
Về vấn đề bảo mật cho Web API, không có một phương pháp chuẩn để đảm bảo. Web API cho phép người dùng phát triển các phương pháp bảo mật phù hợp với ứng dụng của họ. Điều quan trọng là phải hiểu hai giai đoạn quan trọng của triển khai bảo mật Web API:
- Xác thực: Phương pháp này được sử dụng để xác nhận danh tính của người dùng.
- Ủy quyền: Phương pháp này được sử dụng để xác định xem một người dùng cụ thể có được phép thực hiện một nhiệm vụ hay không.
Để hiểu các giai đoạn/quy trình này, hãy xem xét một ví dụ. Người dùng John sử dụng tên người dùng và mật khẩu duy nhất của mình để đăng nhập. Mật khẩu này sau đó được máy chủ sử dụng để xác thực John, đây là giai đoạn xác thực. Khi John đã đăng nhập thành công, giả sử rằng anh ấy có thể truy cập vào một tệp cụ thể, nhưng không thể chỉnh sửa tệp đó. Lúc này là giai đoạn ủy quyền.
Hình bên dưới biểu thị xác thực và ủy quyền trong Web API.
Xác thực
Trong Web API, việc xác thực được thực hiện trên máy chủ. Để xác thực người dùng, Internet Information Server (IIS) sử dụng các mô-đun HTTP. Người dùng có sẵn tùy chọn để chọn các mô-đun xác thực, được cấu hình trong IIS hoặc ASP.NET cho dự án của họ. Nếu cần xác thực tùy chỉnh, họ có thể tạo các mô-đun HTTP phù hợp với yêu cầu của họ.
Máy chủ tạo ra một nguyên tắc gọi là đối tượng IPrincipal cho người dùng đã xác thực. Đối tượng này giúp xác định ngữ cảnh bảo mật đã được chọn. Đối tượng này sau đó được thêm vào luồng hiện tại bằng cách sử dụng Thread.CurrentPrincipal. Nguyên tắc cũng có một đối tượng Identity, chứa tất cả dữ liệu liên quan đến người dùng.
Khi xác thực cho người dùng thành công, thuộc tính Identity.IsAuthenticated cung cấp giá trị ‘true’. Ngược lại, nó cung cấp giá trị ‘false’.
Ủy quyền
Trong khi xác thực diễn ra trên máy chủ, ủy quyền diễn ra gần với controller. Ủy quyền sử dụng các bộ lọc, được áp dụng trước khi hành động của controller thực hiện. Ví dụ, một nhà tuyển dụng có thể lọc dữ liệu với tên nhân viên, trả về dữ liệu liên quan đến nhân viên.
Khi ủy quyền không thành công, các bộ lọc sẽ không được áp dụng và một thông báo lỗi sẽ được hiển thị. Để lấy nguyên tắc hiện tại từ một hành động của controller, xem thuộc tính ApiController.User. Bộ lọc AuthorizeAttribute là một phần quan trọng của Web API. Điều này giúp xác định xem xác thực có thành công hay không. Nếu không thành công, nó hiển thị mã lỗi HTTP 401.
Bộ lọc này có thể được sử dụng toàn cầu hoặc ở cấp độ controller hoặc cấp độ cá nhân như sau:
Toàn cầu: Nếu cần thiết để ngăn chặn truy cập cho tất cả các controller Web API, đảm bảo rằng bộ lọc AuthorizeAttribute được bao gồm trong danh sách bộ lọc toàn cầu trong Global Register0.
Controller: Nếu cần thiết để ngăn chặn truy cập cho một controller cụ thể, đảm bảo rằng bộ lọc được bao gồm như một thuộc tính cho controller trước định nghĩa lớp Controller.
Hành động: Nếu cần thiết để ngăn chặn truy cập cho các hành động cụ thể, đảm bảo rằng thuộc tính được bao gồm trong phương thức hành động.
Xác thực danh tính trong Web API
Việc cung cấp bảo mật cho Web API là rất quan trọng để các nhà phát triển có thể hạn chế người dùng truy cập vào chúng. Dưới đây là các bước để tạo Web API với xác thực dựa trên mã thông báo Open Web Interface for .NET (OWIN):
Bước 1: Tạo một ứng dụng Web ASP.NET mới và đặt tên là StudentServices. Nhấn OK và chọn loại ứng dụng như hình bên dưới. Cũng quan sát các tùy chọn loại xác thực từ menu thả xuống.
Bước 2: Nhấp vào menu thả xuống Xác thực để thực hiện xác thực. Một cửa sổ với các tùy chọn xác thực khác nhau sẽ hiển thị như hình bên dưới.
Bước 3: Sau khi ứng dụng được tạo, mở rộng Solution Explorer. Controller AccountController có thể được nhìn thấy trong thư mục Controllers như hình bên dưới.
Bước 4: Mở file web.config
để cập nhật chuỗi kết nối (Connection string). Mặc định, xác thực OWIN tạo một cơ sở dữ liệu xác thực bên trong thư mục Data. Thay vì vậy, hãy tạo các bảng xác thực trong cơ sở dữ liệu Azure SQL. Để làm được điều này, phần connectionStrings
cần được thay thế như mô tả trong Mã đoạn bên dưới. Trong Mã bên dưới, tên kết nối cơ sở dữ liệu là DefaultConnection
.
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=tcp:azureclouddb.database.windows.net,1433;initial catalog=StudentDb;user id=AZDBAdmin;password=AzDb@2016;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
Bước 5: Chạy ứng dụng. Có thể quan sát rằng ứng dụng MVC mặc định cũng sẽ được tải, đó là một ứng dụng trợ giúp API. Nhấp vào liên kết API để tải trang trợ giúp API. Các phương thức API liên quan đến tài khoản sẽ được liệt kê như hình bên dưới.
Cả hai phương thức Register và Logout có thể thấy, nhưng không có phương thức Login. Phương thức Login hoạt động trong xác thực OWIN như sau:
Bước 6: Dừng ứng dụng và mở file Startup.Auth.cs
trong thư mục App_Start
. Tại đây, bạn có thể thấy mã được hiển thị trong Mã đoạn bên dưới. Cài đặt để tạo mã thông báo (token) – TokenEndpointPath
cũng có thể được tìm thấy ở đây.
OAuthOptions = new OAuthAuthorizationServerOptions(
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(public ClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), // Trong chế độ sản xuất, đặt AllowInsecureHttp = false
AllowInsecureHttp = true
);
Mặc định, đường dẫn hoặc URL này không thể được khám phá, vì vậy nó không hiển thị trong lớp trợ giúp API. Tuy nhiên, bạn có thể gọi đường dẫn này. Trong trường hợp này, đường dẫn là http://localhost:54573/Token. Sử dụng Postman để gọi phương thức API này để tạo mã thông báo từ OWIN.
Để triển khai xác thực và phân quyền, việc đầu tiên là quan trọng để đăng ký người dùng với một id người dùng duy nhất và mật khẩu và sau đó, cố gắng đăng nhập với những thông tin này.
Bước 7: Chạy lại ứng dụng. Mở ứng dụng Postman hoặc tiện ích trình duyệt để đăng ký người dùng. Chọn POST từ menu thả xuống. Hình bên dưới cho thấy đầu ra hiển thị URL để gửi thông tin đăng ký người dùng. Chuyển đối tượng người dùng JSON như được hiển thị trong Mã bên dưới cho phương thức POST.
{
"Email": "alex.g@gmail.com",
"Password": "myPass@123",
"Confirm Password": "myPass@123"
}
Hình bên dưới hiển thị phương thức POST đang chạy trong ứng dụng Postman. Quan sát tất cả các phần được đánh dấu. Mã trạng thái phản hồi là 200, điều này có nghĩa là API đã thực thi thành công và người dùng đã được tạo.
Bước 8: Đăng nhập vào API bằng cách gọi phương thức /Token. Để làm điều này, nhà phát triển cần cung cấp đường dẫn đầy đủ là http://localhost:54573/Token. Các tham số và loại phương thức HTTP được hiển thị như trong Hình bên dưới.
Có thể quan sát rằng phản hồi đại diện cho giá trị Mã thông báo truy cập đã mã hóa, Ngày hết hạn, Loại Mã thông báo, và các thông tin khác. Mã thông báo truy cập này quan trọng vì nó cần được gửi như một đối tượng tiêu đề cho một cuộc gọi API được ủy quyền hơn nữa.
Thông tin đăng nhập được lưu trữ trong các bảng được tạo tự động trong cơ sở dữ liệu Azure. Để xem các bảng này, đăng nhập vào Azure SQL Server bằng SQL Server Management Studio (SSMS). Khi nhà phát triển mở rộng các bảng cơ sở dữ liệu, anh ấy/cô ấy có thể thấy rằng có sáu bảng được tạo.
Trong số sáu bảng, năm bảng bắt đầu bằng tiền tố AspNet. Những bảng này liên quan đến xác thực. Hình bên dưới biểu thị cấu trúc của các bảng.
Tổng quan về CORS và XSRF
Cross-Origin Resource Sharing (CORS) là một tiêu chuẩn của World Wide Web Consortium (W3C). Nó được sử dụng để giảm bớt chính sách cùng nguồn gốc trên máy chủ. Chính sách cùng nguồn gốc là một hạn chế đối với các trang Web để ngăn chặn chúng gửi các yêu cầu AJAX đến một miền khác do vấn đề bảo mật trình duyệt. Điều này ngăn chặn một trang web độc hại truy cập thông tin tài khoản từ một trang web khác. Tuy nhiên, có thể có yêu cầu để các trang web khác có thể gọi Web API đã phát triển. Đây là lúc CORS trở nên hữu ích. CORS cho phép máy chủ chấp nhận một số yêu cầu cùng nguồn gốc trong khi từ chối những yêu cầu khác.
Trước đây, JSON with Padding (JSONP) đã được sử dụng cho mục đích tương tự, nhưng hiện nay CORS được coi là đáng tin cậy và linh hoạt hơn. Bây giờ hãy hiểu cách kích hoạt CORS trong ứng dụng WebService.
Các bước để kích hoạt nó như sau:
Bước 1: Thêm gói CORS NuGet. Để làm điều này, mở Visual Studio 2022, vào menu Tools, và chọn Library Package Manager Package Manager Console. Nhập lệnh sau: Install-Package Microsoft.AspNet.WebApi.Cors
. Sau khi lệnh được thực thi, gói phần mềm mới nhất sẽ được cài đặt. Nó cũng cập nhật tất cả các thực thể liên quan, ví dụ như các thư viện core của Web API. Trường hợp cần phiên bản cụ thể, sử dụng Version. Tuy nhiên, lưu ý rằng Web API phiên bản 2.0 trở lên là cần thiết cho gói CORS này.
Bước 2: Trong tệp App_Start/WebApiConfig.cs
, chèn mã sau vào phương thức WebApiConfig.Register như trong đoạn mã bên dưới:
using System.Web.Http;
namespace WebService {
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Dòng code sau đây sẽ kích hoạt CORS
config.EnableCors();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Bước 3: Thêm thuộc tính [EnableCors
] vào lớp StudentController
như trong đoạn mã bên dưới:
using StudentServices.Models;
using System.Linq;
using System.Web.Http;
namespace StudentServices.Controllers {
[EnableCors(origins: "*", headers: "*", methods: "*")]
[Authorize]
public class StudentController : ApiController {
// Đoạn mã cho các API của Student
}
}
Đối với tham số origin, hãy sử dụng URI nơi ứng dụng WebClient đã được triển khai. Điều này cho phép các yêu cầu cross-origin đến từ WebClient và ngăn các yêu cầu khác là từ cross-domain.
Triển khai các hành động đồng bộ và bất đồng bộ
API đồng bộ/bất đồng bộ trả về dữ liệu cho các yêu cầu ngay lập tức hoặc sau một thời gian sau đó. Chúng cho phép chúng ta thực hiện yêu cầu ngay lập tức hoặc lên lịch cho các tài nguyên, dữ liệu, hoặc dịch vụ khi chúng có sẵn.
Tính đồng bộ và bất đồng bộ của một API phụ thuộc vào thời điểm yêu cầu và trả về dữ liệu. Trong các API đồng bộ, dữ liệu được trả về ngay lập tức. Ứng dụng gửi yêu cầu dữ liệu và đợi cho đến khi có giá trị được trả về. Trong các API bất đồng bộ, sự sẵn có của một tài nguyên, dịch vụ, hoặc cơ sở dữ liệu có thể không ngay lập tức. Loại API này có thể cung cấp một callback cho người yêu cầu khi tài nguyên được yêu cầu đã sẵn sàng. Chúng cung cấp tính năng tốt hơn.
API có thể là đồng bộ khi sự sẵn có dữ liệu hoặc dịch vụ, tài nguyên, và kết nối cao và độ trễ thấp là yêu cầu hoặc nó có thể là bất đồng bộ khi sự sẵn có dữ liệu, dịch vụ, và kết nối thấp với nhu cầu.
Tạo dịch vụ OData
Giao thức Open Data Protocol (OData) là một loại giao thức truy cập dữ liệu cho Web. Nó cung cấp một phương pháp nhất quán để truy vấn và điều khiển tập hợp dữ liệu qua các hoạt động CRUD. Các hoạt động này bao gồm xóa, đọc, cập nhật, và tạo mới.
OData cung cấp một phương pháp chuẩn để truy vấn thông tin và được xây dựng trên REST. Các truy vấn tiêu chuẩn bao gồm các hoạt động giới hạn số đối tượng được trả về, thực hiện phân trang, đếm các phần tử được trả về, chọn các đối tượng dựa trên điều kiện nhất định, và nhiều hơn nữa. ASP.NET Web API hỗ trợ cả hai phiên bản của giao thức, đó là v3 và v4. Nó cũng hỗ trợ một điểm cuối v4 có thể được thực thi cùng với một điểm cuối v3.
Tạo điểm cuối OData bằng ASP.NET Web API
Dưới đây là các bước để tạo dịch vụ OData dựa trên mô hình dữ liệu thực thể sinh viên hiện có:
Bước 1: Tạo một ứng dụng Web ASP.NET
mới hoặc thêm một dự án mới vào giải pháp trước đó. Đặt tên là Student OData. Chọn mẫu Empty và chọn tùy chọn Web API như hình ảnh
Bước 2: Cài đặt OData và Entity Framework từ NuGet bằng cách thực thi lệnh NuGet sau trong Console NuGet:
Install-Package Microsoft.AspNet.Odata
Install-Package EntityFramework
Install-Package Microsoft.AspNet.WebApi.Tracing
Update-Package Microsoft.AspNet.WebApi.WebHost
Đi đến menu Tools và chọn NuGet Package Manager Console.
Bước 3: Thêm một lớp mô hình StudentModel
vào thư mục Models như trong đoạn mã bên dưới.
public class StudentModel {
public int StudentId { get; set; }
public string StudentName { get; set; }
public string StudentEmail { get; set; }
public DateTime StudentJoinDate { get; set; }
}
Bước 4: Thêm một chuỗi kết nối mới trong web.config
như trong đoạn mã bên dưới.
<connectionStrings>
<add name="StudentODataContext" connectionString="Data Source=tcp:azureclouddb.database.windows.net,1433;initial catalog=StudentDb;user id=billsmith;password=Dracula99;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
Bước 5: Cấu hình đường dẫn OData. Mở tệp WebApiConfig.cs
từ thư mục App_Start
để đăng ký đường dẫn của dịch vụ OData và thêm mã như trong đoạn mã bên dưới.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.OData.Builder;
using System.Web.Http.OData.Extensions;
using StudentOData.Models;
namespace StudentOData {
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<StudentModel>("StudentModels");
config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
}
}
}
Bước 6: Để thêm bộ điều khiển, nhấp chuột phải vào thư mục Bộ điều khiển và chọn Thêm mục. Đặt tên cho lớp StudentModelsController
. Tham khảo Hình bên dưới.
Triển khai chức năng OData bằng cách sử dụng StudentDbContext
như được nêu trong Đoạn mã bên dưới:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using System.Web.Http.OData;
using System.Web.Http.OData.Routing;
using StudentOData.Models;
namespace StudentOData.Controllers
{
/* Lớp WebApiConfig có thể yêu cầu thêm các thay đổi để thêm một route cho controller này. Hợp nhất các câu lệnh này vào phương thức Register của lớp WebApiConfig nếu có thể. Lưu ý rằng các URL OData phân biệt chữ hoa chữ thường. */
public class StudentModelsController : ODataController
{
private StudentODataContext db = new StudentODataContext();
// GET: odata/StudentModels
[EnableQuery]
public IQueryable<StudentModel> GetStudentModels()
{
return db.StudentModels;
}
// POST: odata/StudentModels
public IHttpActionResult Post(StudentModel studentModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.StudentModels.Add(studentModel);
db.SaveChanges();
return Created(studentModel);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Bước 7: Thực thi ứng dụng. Điều này hiển thị các thuộc tính OData của Student như trong Hình bên dưới.
Bước 8: Sử dụng Postman để xác minh Dịch vụ OData. URL và dữ liệu được đưa ra trong Hình bên dưới.
Bài tập
Bài 1:
## Yêu cầu:
1. Sử dụng ASP.NET Core để tạo API và kết nối đến cơ sở dữ liệu SQL Server.
2. Sử dụng ReactJS hoặc Angular (tùy thuộc vào khóa học) cho giao diện người dùng.
3. Mã phải được viết rõ ràng, dễ hiểu và có chú thích đầy đủ.
### Câu hỏi 1: Quản lý danh sách sản phẩm và đơn hàng (15 điểm)
#### Mô hình dữ liệu (4 điểm)
Tạo file Product.cs với các thuộc tính sau:
- Id (int, primary key)
- Name (string, required, min length 5, max length 255)
- Price (decimal, required, min value 0)
- Description (string)
- Quantity (int, required, min value 0)
Tạo file Order.cs với các thuộc tính sau:
- Id (int, primary key)
- OrderDate (datetime)
- CustomerId (int, foreign key)
- ProductId (int, foreign key)
- Quantity (int, required, min value 1)
#### API (6 điểm)
Tạo API với các endpoint sau:
- GET /api/products: Lấy danh sách sản phẩm.
- GET /api/products/{id}: Lấy thông tin chi tiết của sản phẩm theo ID.
- POST /api/products: Thêm sản phẩm mới.
- PUT /api/products/{id}: Cập nhật thông tin của sản phẩm theo ID.
- DELETE /api/products/{id}: Xóa sản phẩm theo ID.
- GET /api/orders: Lấy danh sách đơn hàng.
- GET /api/orders/{id}: Lấy thông tin chi tiết của đơn hàng theo ID.
- POST /api/orders: Thêm đơn hàng mới.
#### Giao diện ReactJS (5 điểm)
Tạo giao diện đơn giản bằng ReactJS để:
- Hiển thị danh sách sản phẩm.
- Thêm sản phẩm mới.
- Hiển thị danh sách đơn hàng.
### Câu hỏi 2: Phân trang, Sắp xếp và Tìm kiếm (5 điểm)
#### Phân trang (2 điểm)
Sử dụng thư viện Swashbuckle.AspNetCore để thêm swagger vào API. Cho phép phân trang danh sách sản phẩm và đơn hàng bằng swagger.
#### Sắp xếp (1 điểm)
Cho phép sắp xếp danh sách sản phẩm theo tên, giá hoặc số lượng.
#### Tìm kiếm (2 điểm)
Cho phép tìm kiếm sản phẩm theo tên.
### Ghi chú:
Các tính năng bổ sung có thể được thêm vào để tăng điểm. Giao diện người dùng có thể được tùy chỉnh theo ý muốn.
### Ví dụ về các thư viện có thể sử dụng:
- ASP.NET Core: Microsoft.EntityFrameworkCore, Swashbuckle.AspNetCore
- ReactJS: react-router-dom, axios
Bài 2:
## Yêu cầu:
1. Sử dụng ASP.NET Core để tạo API.
2. Kết nối đến cơ sở dữ liệu SQL Server.
3. Sử dụng ReactJS hoặc AngularJS (tùy thuộc vào khóa học) cho giao diện người dùng.
4. Mã phải được viết rõ ràng, dễ hiểu và có chú thích đầy đủ.
### Câu hỏi 1: Quản lý danh sách bài viết blog và danh mục (15 điểm)
#### Mô hình dữ liệu (3 điểm)
Tạo file Post.cs với các thuộc tính sau:
- Id (int, primary key)
- Title (string, required, min length 5, max length 255)
- Content (string)
- Author (string, required, max length 100)
- PublishedDate (datetime)
- CategoryId (int, foreign key)
Tạo file Category.cs với các thuộc tính sau:
- Id (int, primary key)
- Name (string, required, max length 255)
#### API (6 điểm)
Tạo API với các endpoint sau:
- GET /api/posts: Lấy danh sách bài viết blog.
- GET /api/posts/{id}: Lấy thông tin chi tiết của bài viết blog theo ID.
- POST /api/posts: Thêm bài viết blog mới.
- PUT /api/posts/{id}: Cập nhật thông tin của bài viết blog theo ID.
- DELETE /api/posts/{id}: Xóa bài viết blog theo ID.
#### Giao diện ReactJS (6 điểm)
Tạo giao diện đơn giản bằng ReactJS để:
- Hiển thị danh sách bài viết blog.
- Lọc bài viết blog theo danh mục.
- Thêm bài viết blog mới.
### Câu hỏi 2: Phân trang, Sắp xếp và Tìm kiếm (5 điểm)
#### Phân trang (2 điểm)
Sử dụng thư viện Swashbuckle.AspNetCore để thêm swagger vào API. Cho phép phân trang danh sách bài viết blog bằng swagger.
#### Sắp xếp (1 điểm)
Cho phép sắp xếp danh sách bài viết blog theo tiêu đề, ngày xuất bản hoặc danh mục.
#### Tìm kiếm (2 điểm)
Cho phép tìm kiếm bài viết blog theo tiêu đề.
### Ghi chú:
- Các tính năng bổ sung có thể được thêm vào để tăng điểm.
- Giao diện người dùng có thể được tùy chỉnh theo ý muốn.
### Ví dụ về các thư viện có thể sử dụng:
- ASP.NET Core: Microsoft.EntityFrameworkCore, Swashbuckle.AspNetCore
- ReactJS: react-router-dom, axios