Backend proxy API key trên VPS: giấu key, cache, giới hạn

Chia sẻ bài viết

Mục lục
Backend proxy API key trên VPS: giấu key, cache, giới hạn

Trả lời nhanh: Nguyên tắc bất di bất dịch: API key không bao giờ được nằm trong web app, app mobile hay tiện ích trình duyệt, mọi thứ chạy trên máy người dùng đều bóc ra được. Cách làm đúng là dựng một backend proxy nhỏ trên VPS: app gọi backend của bạn, backend giữ key và gọi tiếp nhà cung cấp AI, đồng thời làm bốn việc mà nhà cung cấp không làm hộ, xác thực người dùng, giới hạn lượt, cache, và ghi log chi phí.

Câu chuyện lặp lại đều đặn trong các nhóm lập trình: một bạn làm sản phẩm AI nhỏ, nhét key vào ứng dụng cho nhanh, vài ngày sau nhận email báo hết credit hoặc hóa đơn tăng vọt vì có người tìm thấy key trong mã nguồn tải về. Bài này là mảnh ghép cuối của series và cũng là mảnh có giá trị nhất, biến một key lộ thiên thành một dịch vụ có kiểm soát, với lượng code ít hơn bạn tưởng.

Tóm tắt nhanh
  • Mọi thứ chạy trên máy người dùng đều bóc được: app web, mobile, extension đều không phải chỗ giấu key
  • Proxy tối thiểu chỉ vài chục dòng: nhận request, kiểm tra quyền, gọi nhà cung cấp, trả kết quả
  • Bốn tính năng đáng tiền: giới hạn theo người dùng, cache, ghi log token, đổi nhà bằng cấu hình
  • Streaming phải chuyển tiếp đúng cách nếu không giao diện chat sẽ đứng hình
  • Đặt trần chi tiêu ở cả hai đầu: trong proxy của bạn và trong bảng điều khiển nhà cung cấp

Vì sao key trong ứng dụng luôn là key đã mất

Nhiều người tin rằng chỉ cần nén, làm rối mã hoặc giấu key trong biến nội bộ là an toàn. Không phải. Với web app, mọi thứ trình duyệt tải về đều đọc được bằng tab Network, kể cả khi key được ghép từ nhiều mảnh. Với app mobile, file cài đặt giải nén ra là thấy chuỗi. Với tiện ích trình duyệt, mã nguồn nằm ngay trong thư mục cài đặt. Các công cụ quét mã nguồn công khai tự động còn liên tục rà GitHub để tìm key bị đẩy nhầm, nhiều người phát hiện key lộ chỉ vài phút sau khi commit.

Hậu quả không dừng ở tiền: người khác dùng key của bạn để tạo nội dung vi phạm, và tài khoản bị khóa vì hành vi họ gây ra. Đó là lý do proxy không phải chuyện làm cho đẹp kiến trúc mà là điều kiện tối thiểu để đưa sản phẩm AI ra ngoài.

Proxy tối thiểu: ít code hơn bạn nghĩ

Bản lõi chỉ làm ba việc: xác thực người gọi, chuyển tiếp request kèm key thật, trả kết quả về. Ví dụ bằng Node với Express:

import express from "express";
const app = express();
app.use(express.json());

app.post("/api/chat", async (req, res) => {
  const user = await xacThucNguoiDung(req.headers.authorization); // phien dang nhap cua ban
  if (!user) return res.status(401).json({ loi: "chua dang nhap" });
  if (!(await conLuot(user.id))) return res.status(429).json({ loi: "het luot hom nay" });

  const r = await fetch(`${process.env.AI_BASE_URL}/chat/completions`, {
    method: "POST",
    headers: { "Authorization": `Bearer ${process.env.AI_API_KEY}`,
               "Content-Type": "application/json" },
    body: JSON.stringify({
      model: process.env.AI_MODEL,
      messages: [{ role: "system", content: process.env.SYSTEM_PROMPT },
                 { role: "user", content: String(req.body.cauHoi).slice(0, 4000) }],
      max_tokens: 800,
    }),
  });
  const data = await r.json();
  await ghiLog(user.id, data.usage);       // token vao/ra de tinh chi phi
  res.json({ traLoi: data.choices?.[0]?.message?.content ?? "" });
});
app.listen(3000);

Ba chi tiết nhỏ nhưng quan trọng nằm sẵn trong đoạn trên: cắt độ dài đầu vào để không ai dán cả cuốn sách vào đốt tiền của bạn; system prompt nằm ở server nên người dùng không sửa được vai của model; và base URL, model, key đều là biến môi trường, đúng thói quen đã dựng từ các bài trước, cho phép đổi nhà cung cấp mà không sửa code.

Bốn tính năng biến proxy thành thứ đáng tiền

1. Giới hạn theo người dùng. Đếm lượt theo tài khoản chứ không chỉ theo IP (IP dễ đổi, tài khoản thì không): mỗi người bao nhiêu lượt mỗi ngày, bao nhiêu token mỗi tháng. Lưu bộ đếm trong Redis hoặc thẳng trong cơ sở dữ liệu bạn đang dùng. Đây là hàng rào chặn cả người lạm dụng lẫn vòng lặp lỗi trong chính ứng dụng của bạn.

2. Cache câu trả lời. Nhiều sản phẩm có tỷ lệ câu hỏi trùng nhau cao đáng ngạc nhiên, hỏi giá, hỏi chính sách, hỏi hướng dẫn. Băm nội dung câu hỏi cùng system prompt làm khóa, lưu kết quả vài giờ. Với những sản phẩm như vậy, cache cắt được phần lớn số lời gọi ra ngoài, tức cắt thẳng vào hóa đơn.

3. Ghi log token theo tính năng. Mỗi bản ghi gồm người dùng, tính năng, model, token vào, token ra, thời gian phản hồi. Sau một tuần bạn biết chính xác tính năng nào đang ngốn tiền và tính năng nào không ai dùng, thông tin mà hóa đơn tổng của nhà cung cấp không bao giờ cho bạn.

4. Chuyển nhà bằng cấu hình. Vì mọi ứng dụng gọi qua proxy, đổi từ nhà này sang nhà khác, hoặc rẽ sang model nội bộ chạy bằng Ollama, chỉ là sửa biến môi trường và khởi động lại. Nhiều đội cài luôn cơ chế dự phòng: nhà chính lỗi thì tự chuyển sang nhà phụ.

Streaming, bảo mật và những chỗ dễ làm sai

Streaming. Nếu giao diện của bạn hiện chữ chảy dần, proxy phải chuyển tiếp luồng chứ không gom trọn rồi mới trả, nghĩa là đọc từng mẩu từ nhà cung cấp và đẩy ngay xuống client qua SSE, đồng thời tắt buffer ở reverse proxy phía trước (với Nginx là proxy_buffering off). Đây là lỗi làm người ta mất nhiều giờ nhất: code đúng nhưng Nginx giữ lại toàn bộ luồng nên người dùng thấy đứng hình rồi bung một cục.

Bảo mật. Bắt buộc HTTPS bằng chứng chỉ Let's Encrypt qua Nginx hoặc Caddy; giới hạn CORS đúng tên miền của bạn thay vì để dấu sao; không đưa nguyên văn lỗi của nhà cung cấp về client vì thông điệp lỗi đôi khi lộ chi tiết cấu hình; và đừng ghi log toàn văn prompt của người dùng nếu sản phẩm chạm dữ liệu cá nhân, ghi số token và mã băm là đủ để tính tiền mà không tạo ra một kho dữ liệu nhạy cảm mới phải bảo vệ.

Chống lạm dụng. Thêm hàng rào đơn giản trước khi gọi model: chặn nội dung quá dài, chặn tần suất bất thường, và với ứng dụng công khai thì yêu cầu đăng nhập. Rẻ hơn nhiều so với việc dọn dẹp sau khi có người chạy kịch bản tự động vào endpoint của bạn.

Đặt proxy ở đâu và cần máy cỡ nào

Bản thân proxy rất nhẹ vì phần tính toán nằm ở phía nhà cung cấp, một VPS 2 vCPU, 4GB RAM phục vụ được lượng người dùng đáng kể. Cái ăn tài nguyên là những thứ mọc lên quanh nó: Redis cho cache và bộ đếm, cơ sở dữ liệu ghi log từng lời gọi (bảng này lớn nhanh hơn bạn nghĩ), và nếu bạn chạy thêm model nội bộ bên cạnh thì nhu cầu nhảy hẳn một bậc. Log và cache là công việc đọc ghi liên tục nhiều bản ghi nhỏ, đúng loại tải mà ổ NVMe tạo khác biệt rõ so với ổ thường.

Về vị trí đặt: nếu người dùng của bạn ở Việt Nam, đặt proxy trong nước giúp cắt phần lớn độ trễ trên quãng đường từ người dùng tới backend; quãng còn lại ra nhà cung cấp quốc tế thì ai cũng như nhau. Cuối cùng, đặt trần chi tiêu ở cả hai đầu, hạn mức trong bảng điều khiển nhà cung cấp và bộ đếm trong proxy của bạn, vì một lớp bảo vệ luôn có ngày hỏng.

Bốn tính năng biến lớp trung gian thành thứ đáng tiền

Tính năngGiải quyết vấn đề gì
Giấu khóa ở phía máy chủKhóa nhúng trong ứng dụng là khóa đã lộ, kể cả trong ứng dụng di động
Giới hạn tần suất theo người dùngMột người dùng bất thường không tiêu hết hạn mức của cả hệ thống
Lưu đệm câu trả lời cho các câu hỏi lặp lạiCắt chi phí đáng kể với các câu hỏi phổ biến
Ghi nhật ký và đo chi phí theo người dùngBiết ai dùng bao nhiêu, và phát hiện lạm dụng sớm

Vì sao khóa trong ứng dụng luôn là khóa đã mất

  • Ứng dụng web: mọi thứ chạy trên trình duyệt đều đọc được, kể cả khi đã làm rối mã.
  • Ứng dụng di động: tệp cài đặt giải nén được, và các công cụ tự động quét khóa trong ứng dụng đã có sẵn.
  • Ứng dụng máy tính để bàn: tương tự, chỉ khó hơn một chút.
  • Hệ quả: mọi khóa gửi tới thiết bị người dùng phải coi là công khai. Không có cách nào giấu được, chỉ có cách không gửi đi.

Những chỗ dễ làm sai

# 1. Quen tat dem cho noi dung rieng cua tung nguoi
#    Dem cau tra loi co du lieu ca nhan la lo du lieu giua cac nguoi dung

# 2. Khong gioi han do dai dau vao
#    Nguoi dung gui mot tai lieu rat lon la mot hoa don rat lon

# 3. Truyen thang moi thu nguoi dung gui len dich vu mo hinh
#    Phai loc va kiem truoc, neu khong ho co the lai mo hinh lam viec khac

# 4. Khong xu ly luong tra ve theo tung phan
#    Voi cau tra loi dai, nguoi dung phai cho rat lau moi thay gi

# 5. Khong dat gioi han so luot moi nguoi moi phut
#    Mot kich ban tu dong cua nguoi khac co the tieu het han muc cua ban

# Kiem: theo doi chi phi theo tuan va theo nguoi dung, khong doi den cuoi thang

Đặt ở đâu và cần máy cỡ nào

  • Lớp trung gian rất nhẹ: phần lớn thời gian là chờ dịch vụ bên ngoài trả lời, nên 1 GB bộ nhớ đủ cho lưu lượng vừa phải.
  • Đặt gần người dùng của bạn. Với khách hàng Việt Nam, máy chủ trong nước tiết kiệm 150 tới 250 ms mỗi lượt.
  • Nếu có lưu đệm, cần thêm bộ nhớ cho phần đệm đó, hoặc dùng một dịch vụ đệm riêng.
  • Đặt giám sát: lớp trung gian chết nghĩa là toàn bộ tính năng liên quan chết theo, và người dùng thấy ngay.

Câu hỏi thường gặp

Ứng dụng của tôi chỉ có vài người dùng nội bộ, có cần proxy không?

Nếu ứng dụng chạy trên máy người dùng thì vẫn cần, vì rủi ro không nằm ở số lượng người mà ở chỗ key bị bóc ra được. Trường hợp duy nhất không cần là script chạy trên chính máy chủ của bạn, khi đó key nằm trong biến môi trường của máy chủ đã là đủ.

Dùng dịch vụ trung gian như OpenRouter thay proxy được không?

Không thay thế hoàn toàn: OpenRouter giúp bạn đổi model dễ dàng nhưng key OpenRouter vẫn không được nằm trong ứng dụng phía người dùng. Nhiều đội dùng cả hai, proxy của mình để xác thực và giới hạn, gọi tiếp OpenRouter để linh hoạt model.

Cache có làm câu trả lời cũ đi không?

Có, nên chỉ cache những câu mà đáp án ổn định như hỏi chính sách, hướng dẫn, thông tin sản phẩm ít đổi. Đặt thời hạn ngắn vài giờ và xóa cache khi dữ liệu nguồn thay đổi. Với hội thoại mang tính cá nhân thì không cache.

Nên viết proxy bằng ngôn ngữ gì?

Ngôn ngữ bạn đang dùng cho backend là lựa chọn đúng, vì phần khó nằm ở xác thực và giới hạn chứ không ở hiệu năng. Node và Python đều có ví dụ sẵn cho streaming, còn nếu đội đã dùng Go hay PHP thì cứ giữ nguyên để dễ vận hành.

Hạ tầng VPS tại Việt Nam của TND
Cloud VPS linh hoạt và VPS NVMe xung cao, IP công cộng riêng, đặt tại Việt Nam
Backend proxy là chỗ hội tụ của mọi thứ trong series: key nằm yên một chỗ, cache và bộ đếm chạy liên tục, log ghi từng lời gọi để biết tiền đi đâu. Đó là tải đọc ghi nhiều bản ghi nhỏ, VPS NVMe của TND với ổ Enterprise U.2 xử lý gọn, đặt tại Việt Nam nên khách trong nước kết nối nhanh.
Dùng thử VPS NVMe, bàn giao trong 5 phútNhu cầu nhẹ hơn? Xem VPS giá rẻ từ 129K

Bài viết liên quan