Tải file ở quy mô lớn: xác thực, lưu trữ và truy cập
Tải file ở quy mô lớn cần xác thực rõ ràng, đường dẫn lưu trữ gọn gàng, liên kết tải xuống hết hạn và quyền mạnh để bảo vệ file người dùng.

Những khó khăn khi người dùng tải file ở quy mô lớn
Việc người dùng tải lên trông đơn giản khi chỉ có vài người thử nghiệm. Mọi thứ trở nên phức tạp khi người thực gửi file thực: ảnh lớn, PDF scan, và những tài liệu lạ với phần mở rộng sai. Lúc đó, tải file ở quy mô lớn không còn là một nút trên form mà trở thành vấn đề an toàn và vận hành.
Những vết nứt đầu tiên thường xuất hiện ở ba nơi: bảo mật, chi phí và quyền riêng tư. Kẻ tấn công cố tải malware, người dùng gửi file mà app không mở được, và đội ngũ vô tình phơi bày tài liệu nhạy cảm qua URL công khai. Hoá đơn lưu trữ tăng, băng thông tăng khi cùng một file bị tải xuống lặp lại.
Ảnh và PDF tạo ra các vấn đề khác nhau. Ảnh có thể rất lớn, có nhiều định dạng, và thường chứa metadata ẩn (như vị trí). Bạn còn cần thumbnails và thay đổi kích thước để ứng dụng nhanh. PDF thì khó preview an toàn, có thể chứa nội dung nhúng, và thường lưu những hồ sơ nhạy cảm (hóa đơn, CMND, hợp đồng) không nên truy cập rộng rãi.
Ở quy mô, bạn thường phải xử lý nhiều người dùng tải cùng lúc, file lớn hơn và tổng dung lượng lớn hơn, nhiều lượt tải và thử lại từ mạng không ổn định, và nhiều quy tắc hơn: đội khác nhau, vai trò khác nhau, nhu cầu lưu trữ khác nhau.
Mục tiêu không chỉ là uploads hoạt động. Mục tiêu là uploads an toàn và dễ quản lý sau vài tháng: quy tắc rõ ràng, đường dẫn lưu trữ dự đoán được, metadata phục vụ audit, và kiểm soát truy cập phù hợp cách doanh nghiệp chia sẻ file.
Lập sơ đồ loại file và ai nên truy cập chúng
Trước khi tối ưu lưu trữ hay bảo mật, hãy rõ ràng về những gì người ta sẽ tải lên và ai được phép xem. Phần lớn vấn đề upload ở quy mô thực ra không phải vấn đề lưu trữ mà là kỳ vọng không khớp về truy cập, lưu giữ và rủi ro.
Bắt đầu bằng cách liệt kê các hạng mục file thực tế, chứ không chỉ documents và images. Một avatar khác biệt nhiều so với một hợp đồng PDF, và ảnh chụp màn hình support khác với báo cáo tháng.
Một cách thực tế để lập sơ đồ uploads là gắn mỗi hạng mục với một mẫu truy cập:
- Avatar và ảnh hồ sơ công khai thường đọc được bởi nhiều người, chỉ chỉnh sửa bởi chủ sở hữu.
- Biên lai và hóa đơn mặc định là riêng tư, chỉ chia sẻ với vai trò tài chính hoặc chủ tài khoản.
- Hợp đồng và file tuân thủ bị hạn chế cao và thường cần trail kiểm toán và quy tắc lưu trữ chặt hơn.
- Báo cáo và xuất dữ liệu có thể chia sẻ trong nhóm nhưng nên giới hạn theo workspace hoặc khách hàng đúng.
- File đính kèm ticket thường riêng tư cho người tham gia ticket và đôi khi có giới hạn thời gian.
Sau đó lấy một bản chụp rủi ro nhanh. Upload có thể ẩn malware, rò rỉ dữ liệu nhạy cảm (CMND, thông tin ngân hàng, hồ sơ y tế), hoặc lộ quyền khi đoán được URL là có thể truy cập. Đó là lý do vì sao tải file ở quy mô lớn phần lớn liên quan đến kiểm soát truy cập chứ không chỉ bytes.
Hiệu năng cũng quan trọng. PDF lớn, ảnh độ phân giải cao và mạng mobile không ổn gây upload không hoàn chỉnh và retry. Quyết định ngay khi nào upload bắt buộc phải thành công (hóa đơn, CMND) và khi nào là tùy chọn (banner hồ sơ).
Với mỗi loại file, trả lời sớm vài câu hỏi để khỏi phải viết lại sau:
- Ai có thể tải lên, xem, thay thế và xóa nó?
- Nó có riêng tư, chia sẻ trong nhóm hay công khai?
- Truy cập có nên hết hạn hoặc có thể thu hồi ngay không?
- Nếu upload bị gián đoạn và thử lại thì sao?
- Lưu bao lâu, và ai có thể xuất nó?
Nếu bạn xây với công cụ như AppMaster, coi những câu trả lời này là quy tắc sản phẩm trước, rồi triển khai vào mô hình dữ liệu và endpoints để quyền nhất quán giữa web và mobile.
Quy tắc xác thực tải file để ngăn vấn đề sớm
Nếu muốn uploads ở quy mô lớn an toàn và dự đoán được, xác thực là tuyến phòng thủ đầu tiên. Quy tắc tốt ngăn file xấu trước khi vào storage, và giảm ticket support vì người dùng nhận được phản hồi rõ ràng.
Bắt đầu với allowlist, không phải blocklist. Kiểm tra phần mở rộng tên tệp và đồng thời xác minh MIME từ nội dung upload. Chỉ dựa vào phần mở rộng dễ bị qua mặt. Chỉ dựa vào MIME cũng có thể không nhất quán giữa thiết bị.
Giới hạn kích thước nên phù hợp với loại tệp và quy tắc sản phẩm. Ảnh có thể chấp nhận 5–10 MB, còn PDF có thể cần ngưỡng cao hơn. Video là một bài toán khác và thường cần pipeline riêng. Nếu có các gói trả phí, liên kết hạn mức với gói để bạn có thể báo "Gói của bạn cho phép PDF lên đến 10 MB" thay vì lỗi mơ hồ.
Một số file cần kiểm tra sâu hơn. Với ảnh, xác thực chiều rộng và chiều cao (và đôi khi tỉ lệ khung) để tránh uploads khổng lồ làm chậm trang. Với PDF, số trang có thể quan trọng khi trường hợp sử dụng mong đợi trong một khoảng nhỏ.
Đổi tên file khi upload. Tên file người dùng thường có dấu cách, emoji, hoặc tên lặp như scan.pdf. Dùng ID sinh ra cộng phần mở rộng an toàn, và lưu tên gốc trong metadata để hiển thị.
Một baseline xác thực phù hợp với nhiều app:
- Allowlist loại (phần mở rộng + MIME), từ chối tất cả còn lại.
- Đặt max size theo loại (và tùy chọn theo gói).
- Xác thực kích thước ảnh và từ chối kích thước cực đoan.
- Xác thực số trang PDF khi trường hợp sử dụng yêu cầu.
- Đổi tên thành filename an toàn, duy nhất và giữ tên gốc trong metadata.
Khi xác thực thất bại, hiện một thông báo rõ ràng mà người dùng có thể hành động, ví dụ “PDF phải dưới 20 MB và 50 trang.” Đồng thời, log chi tiết kỹ thuật cho admin (MIME phát hiện, kích thước, user ID và lý do). Trong AppMaster, các kiểm tra này có thể nằm trong Business Process để mọi đường dẫn upload đều theo cùng quy tắc.
Mô hình dữ liệu cho uploads và metadata
Mô hình dữ liệu tốt làm uploads trở nên nhàm chán. Mục tiêu là theo dõi ai sở hữu file, mục đích của nó, và liệu nó an toàn để sử dụng, mà không ràng buộc app vào một nhà cung cấp lưu trữ duy nhất.
Một mẫu đáng tin cậy là luồng hai bước. Đầu tiên, tạo một bản ghi upload trong DB và trả về upload ID. Thứ hai, upload nhị phân lên storage dùng ID đó. Cách này tránh file bí ẩn trong bucket không có hàng tương ứng, và cho phép áp quyền trước khi bytes di chuyển.
Một bảng uploads đơn giản thường đủ. Trong AppMaster, điều này khớp tốt với mô hình PostgreSQL trong Data Designer và có thể dùng trên web và mobile.
Lưu những gì bạn thực sự cần cho hỗ trợ và kiểm toán:
- Tham chiếu chủ sở hữu (
user_id) và phạm vi (org_idhoặcteam_id) - Mục đích (avatar, invoice_pdf, ticket_attachment)
- Tên gốc, MIME phát hiện và
size_bytes - Con trỏ lưu trữ (bucket/container,
object_key) cùng checksum (tùy chọn) - Timestamp (
created_at,uploaded_at) và IP/device của uploader (tùy chọn)
Giữ mô hình trạng thái nhỏ để dễ đọc. Bốn trạng thái phủ hợp hầu hết sản phẩm:
pending: bản ghi tồn tại, upload chưa hoàn tấtuploaded: bytes đã lưuverified: đã qua kiểm tra và sẵn sàng dùngblocked: thất bại kiểm tra hoặc vi phạm chính sách
Lên kế hoạch dọn dẹp từ ngày đầu. pending bị bỏ dở xảy ra khi người dùng đóng tab hoặc mất kết nối. Một job hàng ngày có thể xóa object lưu trữ cho các hàng pending hết hạn, đánh dấu hàng là canceled để báo cáo, xóa các mục blocked cũ sau window lưu trữ, và giữ verified cho đến khi quy tắc nghiệp vụ yêu cầu.
Mô hình này cho bạn khả năng truy vết và kiểm soát mà không thêm phức tạp.
Tổ chức lưu trữ để gọn gàng theo thời gian
Khi uploads ở quy mô lớn bắt đầu chất đống, rủi ro lớn nhất không phải chi phí lưu trữ mà là sự lộn xộn. Nếu đội không biết file là gì, thuộc về ai và có còn hợp lệ không, bạn sẽ phát sinh bug và rò rỉ dữ liệu.
Chọn một chiến lược thư mục có thể dự đoán và bám sát nó. Nhiều đội tổ chức theo tenant (công ty), rồi theo mục đích, rồi theo ngày. Những người khác làm tenant, user, mục đích. Lựa chọn cụ thể quan trọng ít hơn tính nhất quán. Ngày giúp thư mục không tăng không giới hạn và làm job dọn dẹp dễ hơn.
Tránh đặt dữ liệu cá nhân trong đường dẫn hoặc tên tệp. Đừng nhúng email, tên đầy đủ, số hóa đơn hay số điện thoại. Dùng ID ngẫu nhiên thay vào. Nếu cần tìm kiếm theo ý nghĩa con người, lưu trong metadata DB chứ không phải object key.
Giữ originals và derivatives tách biệt để quy tắc rõ ràng. Lưu file gốc một lần, và lưu thumbnails hoặc preview dưới prefix khác. Điều này giúp áp retention và quyền khác nhau (preview có thể cho phép ở nhiều nơi hơn bản gốc).
Một cách đặt tên đơn giản và bền:
- Phân vùng theo tenant ID (hoặc workspace ID)
- Thêm prefix mục đích (avatars, invoices, attachments)
- Thêm bucket thời gian (YYYY/MM)
- Dùng file ID mờ làm tên file
- Lưu derivatives dưới prefix riêng (previews, thumbnails)
Quyết định cách xử lý phiên bản. Nếu người dùng có thể thay file, hoặc ghi đè cùng object key (đơn giản, không có lịch sử) hoặc tạo phiên bản mới và đánh dấu cũ là inactive (thân thiện với kiểm toán). Nhiều đội giữ lịch sử cho tài liệu tuân thủ và ghi đè cho ảnh hồ sơ.
Ghi chép quy tắc đặt tên. Trong AppMaster, coi đó như tập convention chia sẻ: lưu trong tài liệu dự án để backend logic, UI builders và tích hợp tương lai đều sinh cùng đường dẫn.
Mẫu quyền và mô hình kiểm soát truy cập
Với uploads ở quy mô, quyền là nơi những shortcut nhỏ trở thành sự cố lớn. Bắt đầu với deny-by-default: mọi file tải lên mặc định là riêng tư cho đến khi quy tắc cho phép rõ ràng.
Nên tách hai câu hỏi: ai có thể xem bản ghi, và ai có thể lấy bytes. Chúng không giống nhau. Nhiều app cho phép xem metadata (tên file, kích thước, ngày tải) mà không cho phép tải file.
Mô hình truy cập phổ biến
Chọn một mẫu chính cho mỗi loại file, rồi thêm ngoại lệ cẩn trọng:
- Chỉ chủ sở hữu: chỉ uploader (và tài khoản dịch vụ) có thể tải xuống.
- Dựa trên nhóm: thành viên workspace/project có thể tải xuống.
- Dựa trên vai trò: vai trò như Finance hoặc HR có thể tải qua các nhóm.
- Chia sẻ bằng liên kết: token đặc biệt cho phép tải, thường kèm expiry và phạm vi.
Trường hợp méo cạnh cần quy tắc rõ, không phải sửa một lần. Quyết định admin làm thế nào (toàn quyền hay chỉ vài hạng mục), support lấy quyền tạm thời ra sao (giới hạn thời gian và có log), và khi người dùng bị xóa thì xử lý file thế nào (giữ cho tuân thủ, chuyển quyền sở hữu hoặc xóa).
Đối xử metadata và download riêng
Một mẫu đơn giản là hai kiểm tra: (1) người dùng có thể đọc bản ghi upload không, (2) người dùng có thể yêu cầu phản hồi tải xuống không. Kiểm tra thứ hai là nơi bạn áp “riêng tư trừ khi cho phép”, ngay cả khi ai đó đoán được ID.
Với tài liệu nhạy cảm, hãy ghi log truy cập. Ít nhất, ghi ai đã tải (user ID và vai trò), gì đã được tải (file ID và loại), khi nào (timestamp), vì sao được cho phép (kết quả chính sách, share token, override admin), và từ đâu (IP hoặc device, nếu phù hợp).
Trong AppMaster, những quy tắc này thường nằm trong Business Process Editor: một flow để liệt kê metadata upload, và một flow chặt hơn để sinh phản hồi tải xuống.
Liên kết tải xuống hết hạn: tải an toàn hơn mà không phiền người dùng
Liên kết tải xuống hết hạn là giải pháp hợp lý giữa “ai có URL đều tải mãi mãi” và “người dùng phải đăng nhập mỗi lần”. Chúng phù hợp cho tải một lần, chia sẻ qua email, hoặc cấp quyền tạm thời cho nhà thầu. Ở quy mô, chúng cũng giảm vấn đề support vì bạn có thể cấp quyền mà không mở toàn bộ storage.
Hai mô hình phổ biến:
- Signed URLs tự hết hạn. Chúng đơn giản và nhanh, nhưng khó thu hồi nếu link đã lan truyền.
- Endpoint tải dựa trên token cho phép kiểm soát nhiều hơn. Link có token ngắn, app kiểm tra quyền ở mỗi yêu cầu rồi phục vụ hoặc chuyển hướng tới file.
Một thiết lập thực tế:
- Dùng thời hạn ngắn cho link chia sẻ (10–60 phút) và làm mới khi cần.
- Giữ thời hạn dài hơn chỉ cho phiên làm việc đăng nhập tin cậy (ví dụ, “Tải lại” sinh link mới).
- Phạm vi link chặt: một file, một user (hoặc người nhận), một hành động (xem hoặc tải).
- Ghi log tạo link và sử dụng để truy vết rò rỉ khi cần.
Phạm vi quan trọng vì xem thường là hiển thị inline, còn download nghĩa là lưu bản sao. Nếu cần cả hai, tạo link riêng cho từng hành động với quy tắc riêng.
Lên kế hoạch thu hồi. Nếu người dùng mất quyền (hoàn tiền, đổi vai trò, kết thúc hợp đồng), signed URLs có thể không đủ. Với endpoint token, bạn có vô hiệu token ngay. Với signed URLs, dùng thời hạn ngắn và xoay khóa ký khi cần (xoay khóa sẽ thu hồi mọi thứ nên dùng cẩn trọng).
Ví dụ: link hóa đơn trong portal khách hàng gửi cho kế toán hết hạn sau 30 phút, chỉ cho xem, và liên kết với invoice ID cộng account khách hàng. Nếu khách hàng bị xóa khỏi account, token bị từ chối ngay cả khi email được chuyển tiếp.
Các bước: luồng upload có thể mở rộng
Luồng upload đáng tin tách ba mối quan tâm: cái bạn cho phép, bytes đi đâu, và ai có thể lấy sau này. Khi các phần này bị trộn, các edge case nhỏ biến thành sự cố production.
Luồng thực tế cho ảnh, PDF và hầu hết file do người dùng tạo:
- Xác định quy tắc theo mục đích. Với mỗi mục đích (avatar, invoice, ID document), đặt loại cho phép, max size và kiểm tra thêm như số trang.
- Tạo yêu cầu upload trên backend. Client xin phép tải lên. Backend trả về target upload (ví dụ object storage key và token ngắn hạn) và tạo hàng upload mới với trạng thái
pending. - Upload bytes lên storage, rồi xác nhận. Client upload tới object storage, sau đó gọi backend để xác nhận hoàn tất. Backend kiểm tra key mong đợi và thuộc tính cơ bản, rồi đánh dấu hàng
uploaded. - Chạy xác minh bất đồng bộ. Ở nền, xác minh loại file thực (tốt nhất gồm magic bytes), kiểm tra kích thước, trích metadata an toàn (kích thước ảnh, số trang), và tùy chọn quét malware. Nếu thất bại, đánh dấu
blockedvà ngăn tải xuống. - Phục vụ tải xuống theo chính sách. Khi tải, xác minh người dùng có quyền với thực thể sở hữu file (user, org, ticket, order). Sau đó proxy file hoặc trả về signed link hết hạn để giữ storage riêng tư.
Thêm dọn dẹp. Xóa các uploads pending bị bỏ dở sau cửa sổ ngắn, và loại bỏ file không được tham chiếu (ví dụ người dùng tải ảnh nhưng không lưu form).
Nếu xây trong AppMaster, mô hình uploads như một entity với trường status và tham chiếu owner, rồi áp cùng kiểm tra quyền trong mọi Business Process tải xuống.
Ví dụ: hóa đơn trong portal khách hàng
Portal khách hàng nơi người dùng tải hóa đơn PDF nghe có vẻ đơn giản cho tới khi bạn có hàng nghìn công ty, nhiều vai trò, và cùng hóa đơn bị thay ba lần.
Với tổ chức lưu trữ, giữ file thô trong đường dẫn có thể dự đoán tương ứng cách người ta tìm. Ví dụ: invoices/<company_id>/<yyyy-mm>/<upload_id>.pdf. Company và tháng giúp dọn dẹp và báo cáo, còn upload_id tránh va chạm khi hai file cùng tên.
Trong DB, lưu metadata giải thích file là gì và ai có quyền truy cập:
company_idvàbilling_monthuploaded_by_user_idvàuploaded_atoriginal_filenamevàcontent_typesize_bytesvà checksum (tùy chọn)- status (active, replaced, quarantined)
Giờ chia sẻ: một billing manager muốn gửi một hóa đơn cho kế toán bên ngoài trong 24 giờ. Thay vì thay đổi quyền toàn cục, tạo liên kết tải xuống có thời hạn gắn với hóa đơn đó, với expiry nghiêm ngặt và mục đích đơn (chỉ download). Khi kế toán click, app kiểm tra token, xác nhận chưa hết hạn, rồi phục vụ file.
Nếu người dùng tải sai PDF hoặc thay file, đừng ghi đè object cũ. Đánh dấu bản ghi trước là replaced, giữ nó cho audit, và trỏ mục invoice tới upload_id mới. Nếu cần tuân thủ retention, bạn có thể xóa file bị thay sau bằng job định kỳ.
Khi support nhận ticket “không thể tải”, metadata giúp chẩn đoán nhanh: link đã hết hạn, invoice đã bị replaced, người dùng có thuộc công ty đúng không, hay file bị quarantined? Trong AppMaster, các kiểm tra này có thể nằm trong Business Process để mọi tải xuống theo cùng quy tắc.
Sai lầm phổ biến và cách tránh
Khi các đội lần đầu xử lý uploads ở quy mô, lỗi hiếm khi bí ẩn. Chúng đến từ vài shortcut dễ đoán trông ổn trong demo nhưng gây hại sau này.
- Chỉ tin phần mở rộng hay chỉ MIME. Kẻ tấn công có thể đổi tên file, và trình duyệt có thể báo sai. Kiểm tra cả hai và xác minh magic bytes phía server.
- Dùng storage công khai và hy vọng quyền đủ. Bucket/container công khai biến mọi quy tắc bỏ sót thành rò rỉ dữ liệu. Giữ storage riêng tư theo mặc định và kiểm soát truy cập qua app.
- Đặt tên do người dùng cung cấp trong đường dẫn hoặc URL. Tên như invoice_john_smith.pdf lộ thông tin cá nhân và dễ đoán. Dùng ID ngẫu nhiên cho object keys, lưu tên hiển thị trong metadata.
- Trộn files của nhiều tenant trong cùng đường dẫn mà không kiểm tra mạnh. Đường dẫn như /uploads/2026/01/ không phải mô hình quyền. Luôn xác minh tenant và quyền người dùng trước khi trả về tải xuống.
- Bỏ qua dọn dẹp uploads thất bại hoặc bị bỏ dở. Multi-part và retry để lại rác. Thêm job nền xóa pending uploads không hoàn thành.
Một lỗi ít ai nhớ là không có kế hoạch cho retry và trùng lặp. Mạng mobile rớt. Người dùng chạm hai lần. Hệ thống nên xem “tải cùng file lại” là bình thường.
Cách thực tế là tạo upload ID trước, sau đó chấp nhận chunk hoặc một file, và đánh dấu verified chỉ sau khi xác thực qua. Nếu upload lặp lại cùng nội dung, trả về bản ghi tồn tại thay vì tạo bản sao mới.
Nếu xây trong AppMaster, giữ quy tắc lõi ở một nơi (logic backend) để web và mobile hành xử giống nhau ngay cả khi UI thay đổi.
Checklist nhanh trước khi ra mắt
Trước khi mở uploads cho người dùng thực, rà soát nhanh các nền tảng. Hầu hết vấn đề với uploads ở quy mô đến từ những kẽ hở nhỏ chỉ xuất hiện sau khi có nhiều người dùng, nhiều file và nhiều edge case.
- Allowlist loại file và đặt giới hạn kích thước theo trường hợp (avatar vs invoice). Xác thực cả phần mở rộng và loại nội dung thực.
- Lưu metadata upload trong DB: ai sở hữu (user, team, account), mục đích, và trạng thái rõ ràng như
pending,verified, hoặcblocked. - Giữ lưu trữ riêng tư theo mặc định, và kiểm tra quyền ở mọi lần tải xuống (không dựa vào URL ẩn).
- Dùng liên kết tải xuống hết hạn khi cần chia sẻ, và giữ thời lượng ngắn (phút hoặc giờ, không phải ngày).
- Tránh dữ liệu cá nhân trong đường dẫn và tên file. Dùng ID ngẫu nhiên và hiển thị tên thân thiện trong UI.
Có kế hoạch cho uploads bị bỏ dở. Người dùng bắt đầu upload rồi không hoàn tất là bình thường, hoặc thay file thường xuyên.
Một kế hoạch dọn dẹp đơn giản:
- Xóa file cô lập chưa đạt
verifiedsau thời gian định trước. - Giữ retention cho file bị thay rồi xóa sau khoảng thời gian.
- Ghi log sự kiện chính (upload, validation, download, delete) để support điều tra.
Nếu xây trong AppMaster, lưu metadata trong PostgreSQL qua Data Designer, áp checks trong Business Process Editor, và sinh token tải xuống ngắn hạn trước khi phục vụ file.
Bước tiếp theo: phát hành an toàn, rồi cải tiến từng bước nhỏ
Cách nhanh nhất để có bản phát hành an toàn là chọn một cách tiếp cận upload và kiên trì với nó. Quyết định file đi qua backend trước hay upload trực tiếp lên object storage với token ngắn hạn. Rồi viết rõ từng bước và ai chịu trách nhiệm (client, backend, storage). Tính nhất quán hơn là thông minh khi xử lý uploads ở quy mô.
Bắt đầu với mặc định nghiêm ngặt. Giới hạn loại file chỉ những gì cần thiết, giữ giới hạn kích thước thận trọng, và yêu cầu xác thực cho mọi thứ không công khai. Nếu người dùng yêu cầu file lớn hơn hoặc nhiều định dạng hơn, nới lỏng từng quy tắc một và đo lường tác động.
Thêm monitoring cơ bản sớm để lỗi hiện ra nhanh:
- Tỷ lệ thất bại upload (theo thiết bị, trình duyệt, loại file)
- Kích thước trung bình và p95 của upload
- Thời gian để upload (đặc biệt trên mobile)
- Tăng trưởng lưu trữ theo ngày hoặc tuần
- Lỗi tải xuống (bao gồm link hết hạn hoặc bị cấm)
Nếu hệ thống upload là một phần của app lớn hơn, giữ mô hình dữ liệu và quyền gần với logic nghiệp vụ. Các đội dùng AppMaster thường đặt bản ghi upload trong PostgreSQL, thực hiện validation và kiểm soát truy cập file trong Business Processes, và tái sử dụng cùng logic trên backend, web và native mobile.
Một cải tiến hữu ích tiếp theo là thêm preview cho các định dạng phổ biến, log kiểm toán cho tài liệu nhạy cảm, hoặc quy tắc retention đơn giản (ví dụ tự xóa uploads tạm sau 30 ngày). Những nâng cấp nhỏ, ổn định giúp hệ thống đáng tin cậy khi lưu lượng tăng.
Câu hỏi thường gặp
Bắt đầu bằng cách viết ra các loại tệp thực tế bạn dự đoán: avatar, hóa đơn, hợp đồng, file đính kèm ticket, xuất dữ liệu, v.v. Với mỗi loại, quyết định ai có thể tải lên, ai có thể xem, ai có thể thay thế hoặc xóa, chia sẻ có hết hạn không, và thời gian lưu trữ là bao lâu. Những quyết định này định hướng mô hình dữ liệu và kiểm tra quyền để bạn không phải xây lại sau.
Dùng allowlist và kiểm tra cả phần mở rộng tên tệp lẫn MIME thực tế được phát hiện từ nội dung. Đặt giới hạn kích thước rõ ràng theo mục đích tệp và thêm kiểm tra sâu hơn khi cần, ví dụ kích thước ảnh hoặc số trang PDF. Đổi tên tệp thành ID sinh ngẫu nhiên và lưu tên gốc trong metadata để tránh xung đột và tên tệp không an toàn.
Phần mở rộng dễ bị giả mạo, và MIME có thể khác nhau giữa thiết bị và trình duyệt. Kiểm tra cả hai giúp phát hiện nhiều giả mạo cơ bản, nhưng với uploads rủi ro cao nên xác minh chữ ký tệp (magic bytes) trên server khi xác minh. Xử lý mọi thứ thất bại là blocked và ngăn tải xuống cho đến khi được xem xét hoặc xóa.
Tạo trước một bản ghi trong cơ sở dữ liệu rồi trả về upload ID, sau đó tải nhị phân lên và xác nhận hoàn tất. Cách này ngăn các “tệp bí ẩn” nằm trong bucket không có chủ đích, và cho phép áp dụng quyền trước khi bytes được gửi. Nó cũng giúp dọn dẹp vì bạn dễ tìm các upload pending bị bỏ dở.
Giữ lưu trữ ở chế độ riêng tư theo mặc định và kiểm soát truy cập qua logic quyền của ứng dụng. Đặt object key có thể dự đoán nhưng không chứa thông tin cá nhân: dùng tenant/workspace ID cộng upload ID mờ, và lưu thông tin thân thiện với người dùng trong cơ sở dữ liệu. Tách originals và derivatives (thumbnails, previews) để tránh lẫn lộn chính sách lưu trữ và quyền.
Xử lý metadata và việc tải xuống như hai quyền khác nhau. Nhiều người có thể được phép xem rằng có file tồn tại mà không được tải xuống. Luôn áp dụng nguyên tắc deny-by-default cho việc tải xuống, ghi log truy cập với tài liệu nhạy cảm và tránh “bảo mật bằng URL không đoán được” làm cơ chế chính.
Signed URLs nhanh và đơn giản, nhưng khi link đã chia sẻ bạn thường không thể thu hồi cho đến khi nó hết hạn. Endpoint tải xuống dựa trên token cho phép kiểm tra quyền với mỗi yêu cầu và thu hồi ngay bằng cách vô hiệu hóa token. Trong thực tế, thời hạn ngắn kết hợp với phân quyền chặt chẽ cho một file và một hành động giảm rủi ro mà ít gây phiền toái.
Thiết kế hệ thống coi retry là hành vi bình thường: kết nối mobile rớt, người dùng bấm hai lần, uploads trùng lặp. Sinh upload ID trước, chấp nhận upload cho ID đó và làm bước xác nhận idempotent để lặp lại không tạo bản sao thừa. Nếu muốn giảm trùng lặp, lưu checksum sau khi upload và phát hiện re-upload cùng nội dung cho cùng mục đích.
Pending uploads tích tụ khi người dùng bỏ dở form hoặc mất kết nối, nên lên lịch dọn dẹp ngay từ đầu. Hết hạn và xóa các bản pending cùng các object lưu trữ tương ứng, và giữ các mục blocked chỉ trong thời gian cần điều tra. Với các file bị thay thế, giữ retention window rồi xóa các phiên bản cũ tự động.
Mô hình uploads như một thực thể trong PostgreSQL có trường status, owner, scope và purpose, rồi áp dụng quy tắc trong một luồng backend để web và mobile cùng hành xử giống nhau. Đưa bước validation và verification vào Business Process để mọi đường dẫn upload dùng cùng allowlist, giới hạn và chuyển trạng thái. Phục vụ tải xuống qua Business Process chặt chẽ hơn, kiểm tra quyền và cấp token tải xuống ngắn hạn khi cần chia sẻ.


