Table Of Content
- 1. Giới Thiệu
- Audit Trail là gì?
- Tại sao cần Audit Trail trong ASP.NET Core?
- 2. Cấu Trúc Dữ Liệu Audit Trail
- Thiết Kế Bảng AuditLogs
- 3. Thêm Audit Trail Vào DbContext
- Bước 1: Thêm DbSet AuditLogs vào DbContext
- Bước 2: Ghi Log Trước Khi Lưu Dữ Liệu
- 4. Hiển Thị Lịch Sử Audit Trail Trong API
- Bước 1: Tạo AuditController
- 5. Cải Tiến Audit Trail
- Lưu Audit Logs vào một Database Riêng
- Tạo Background Job Để Lưu Audit Logs
- Phân Loại Mức Độ Audit Logs
- Ghi Logs Theo Người Dùng
- 6. Kết Luận
1. Giới Thiệu
Audit Trail là gì?
Audit Trail (theo dõi nhật ký hoạt động) là một cơ chế giúp ghi lại toàn bộ lịch sử thay đổi dữ liệu trong hệ thống. Điều này đặc biệt quan trọng đối với ứng dụng doanh nghiệp, nơi cần giám sát các thay đổi dữ liệu để tuân thủ quy định hoặc kiểm tra bảo mật.
Audit Trail có thể theo dõi nhiều loại thay đổi khác nhau, bao gồm:
- Thêm mới dữ liệu (Insert)
- Cập nhật dữ liệu (Update)
- Xóa dữ liệu (Delete)
- Các thao tác phức tạp hơn như thay đổi trạng thái hoặc quyền hạn của một người dùng.
Tại sao cần Audit Trail trong ASP.NET Core?
- Theo dõi thay đổi dữ liệu: Ai thay đổi gì, khi nào?
- Cải thiện bảo mật: Hỗ trợ điều tra trong trường hợp có hành vi đáng ngờ.
- Tuân thủ quy định: GDPR, HIPAA yêu cầu ghi lại thay đổi dữ liệu quan trọng.
- Phục hồi dữ liệu: Cho phép khôi phục dữ liệu trong một số tình huống.
- Hỗ trợ kiểm toán nội bộ: Cung cấp dữ liệu để kiểm tra việc sử dụng hệ thống.
Trong bài viết này, chúng ta sẽ triển khai Audit Trail bằng EF Core trong một ứng dụng ASP.NET Core.
2. Cấu Trúc Dữ Liệu Audit Trail
Thiết Kế Bảng AuditLogs
Chúng ta cần một bảng để lưu lại lịch sử thay đổi:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class AuditLog { public int Id { get; set; } public string TableName { get; set; } public string Action { get; set; } // Insert, Update, Delete public string KeyValues { get; set; } // Giá trị khóa chính public string OldValues { get; set; } // Dữ liệu cũ public string NewValues { get; set; } // Dữ liệu mới public string ChangedBy { get; set; } // Người thực hiện thay đổi public DateTime ChangedAt { get; set; } // Thời điểm thay đổi public string IpAddress { get; set; } // Địa chỉ IP thực hiện thay đổi } |
Thêm IpAddress để theo dõi địa chỉ IP của người thực hiện thay đổi, giúp tăng cường bảo mật.
3. Thêm Audit Trail Vào DbContext
Chúng ta sẽ override phương thức SaveChanges
để theo dõi thay đổi dữ liệu trước khi lưu vào database.
Bước 1: Thêm DbSet AuditLogs vào DbContext
1 2 3 4 5 6 7 |
public class AppDbContext : DbContext { public DbSet<AuditLog> AuditLogs { get; set; } public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } } |
Bước 2: Ghi Log Trước Khi Lưu Dữ Liệu
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public override int SaveChanges() { var auditEntries = new List<AuditLog>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.State == EntityState.Added || entry.State == EntityState.Modified || entry.State == EntityState.Deleted) { var auditLog = new AuditLog { TableName = entry.Entity.GetType().Name, Action = entry.State.ToString(), KeyValues = JsonSerializer.Serialize(entry.Properties.Where(p => p.Metadata.IsPrimaryKey()).Select(p => new { p.Metadata.Name, p.CurrentValue })), OldValues = entry.State == EntityState.Modified ? JsonSerializer.Serialize(entry.OriginalValues.Properties.ToDictionary(p => p.Name, p => entry.OriginalValues[p])) : null, NewValues = entry.State == EntityState.Added || entry.State == EntityState.Modified ? JsonSerializer.Serialize(entry.CurrentValues.Properties.ToDictionary(p => p.Name, p => entry.CurrentValues[p])) : null, ChangedBy = "System", // Lấy từ UserContext nếu có ChangedAt = DateTime.UtcNow, IpAddress = "127.0.0.1" // Lấy từ HttpContext nếu có }; auditEntries.Add(auditLog); } } AuditLogs.AddRange(auditEntries); return base.SaveChanges(); } |
Thêm IpAddress để theo dõi địa chỉ IP của người dùng, giúp cải thiện bảo mật hệ thống.
4. Hiển Thị Lịch Sử Audit Trail Trong API
Chúng ta sẽ thêm một API để truy vấn lịch sử Audit Trail.
Bước 1: Tạo AuditController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[Route("api/audit")] [ApiController] public class AuditController : ControllerBase { private readonly AppDbContext _context; public AuditController(AppDbContext context) { _context = context; } [HttpGet] public async Task<IActionResult> GetAuditLogs() { var logs = await _context.AuditLogs.OrderByDescending(a => a.ChangedAt).ToListAsync(); return Ok(logs); } } |
Gọi API:
1 2 |
GET /api/audit |
5. Cải Tiến Audit Trail
Lưu Audit Logs vào một Database Riêng
- Tránh làm chậm database chính.
- Dùng một DbContext riêng chỉ dành cho Audit Logs.
Tạo Background Job Để Lưu Audit Logs
- Dùng Hangfire, Azure Functions hoặc Kafka để ghi logs mà không ảnh hưởng đến hiệu suất ứng dụng.
Phân Loại Mức Độ Audit Logs
- Audit logs chi tiết: Lưu mọi thay đổi của ứng dụng.
- Audit logs tối giản: Chỉ lưu những thay đổi quan trọng.
Ghi Logs Theo Người Dùng
- Dùng
HttpContextAccessor
để lấy thông tin user đang thao tác.
1 2 3 |
var user = _httpContextAccessor.HttpContext?.User?.Identity?.Name ?? "Unknown"; auditLog.ChangedBy = user; |
6. Kết Luận
Audit Trail là một tính năng quan trọng giúp theo dõi lịch sử thay đổi dữ liệu trong ứng dụng ASP.NET Core. Bằng cách ghi logs từ ChangeTracker của EF Core, chúng ta có thể lưu lại toàn bộ thay đổi một cách tự động mà không cần chỉnh sửa nhiều vào code business logic.
🚀 Bạn có thể mở rộng tính năng Audit Trail bằng cách:
- Lưu logs vào Elasticsearch để phân tích logs dễ dàng hơn.
- Xây dựng giao diện UI để hiển thị lịch sử thay đổi dữ liệu.
- Thêm bộ lọc và phân quyền cho Audit Logs.
- Sử dụng Kafka hoặc RabbitMQ để xử lý logs theo thời gian thực.
Chúc bạn triển khai thành công! 🎯
No Comment! Be the first one.