Lần đầu xây dựng một tích hợp GitHub, bạn sẽ mất một giờ để tìm hiểu mình muốn GitHub App hay OAuth App. Tài liệu coi chúng như các lựa chọn tương đương. Không phải vậy. Chỉ riêng câu chuyện webhook thường cũng đủ để quyết định thay bạn.
Tóm tắt rất ngắn
- GitHub App: được cài trên tài khoản hoặc repository, có quyền chi tiết, nhận webhook cho các tài nguyên nó được cài, tự xác thực bằng token ngắn hạn.
- OAuth App: người dùng ủy quyền cho nó, nó hành động thay họ với quyền của họ, chỉ nhận webhook nếu tự thiết lập như mọi công cụ bên thứ ba, xác thực dưới danh nghĩa người dùng bằng token dài hạn.
Nếu bạn xây thứ gì đó vận hành mà không có người dùng đang hoạt động — một bot CI, tự động hóa review code, bất cứ thứ gì chạy theo lịch — bạn cần GitHub App. Nếu bạn xây một công cụ thực hiện hành động thay cho người dùng đã đăng nhập (như UI tìm kiếm code), OAuth App là hình thái đúng.
Chúng nhận webhook ra sao
GitHub Apps
Bạn cấu hình một URL webhook khi tạo app. Khi người dùng cài app lên một tài khoản hoặc repository, GitHub bắt đầu gửi sự kiện của phạm vi đó tới URL của bạn. Sự kiện gồm installation (vòng đời cài/gỡ), installation_repositories (repo được thêm hoặc bỏ) và các loại sự kiện app của bạn đăng ký (push, pull_request, v.v.).
Mỗi sự kiện có một header X-GitHub-Hook-Installation-Target-Type ("integration") và một installation ID dùng để đúc token cho lần cài cụ thể đó. Chữ ký là HMAC SHA-256 trong X-Hub-Signature-256 — cùng hình thái với webhook repository.
OAuth Apps
OAuth App không có đăng ký webhook tích hợp sẵn. Để nhận webhook, người dùng đã ủy quyền cho app phải tạo webhook repository hoặc organization trỏ tới URL của app. Nghĩa là tầm với webhook của app gắn với nơi người dùng thiết lập đăng ký, chứ không phải nơi bản thân app được "cài".
Một số nhóm xây OAuth App tự động tạo webhook qua GitHub API sau khi ủy quyền. Cách này chạy được, nhưng giờ bạn quản lý vòng đời webhook theo từng người dùng song song với logic riêng của app.
Xác thực mới là điểm phân kỳ thật sự
GitHub App xác thực bằng các yêu cầu ký JWT để đúc token cài đặt ngắn hạn (1 giờ) cho mỗi lần cài. JWT được ký bằng khóa riêng bạn tạo khi tạo app. Mã của bạn:
// 1. Ký một JWT bằng khóa riêng của app (hết hạn sau 10 phút)
const jwt = createAppJwt(APP_ID, PRIVATE_KEY);
// 2. Đổi JWT lấy token cài đặt (dùng được 1 giờ)
const token = await fetchInstallationToken(jwt, INSTALLATION_ID);
// 3. Gọi API bằng token đó
const res = await fetch('https://api.github.com/repos/x/y/issues', {
headers: { Authorization: `token ${token}` },
});
Token cài đặt bị giới hạn theo lần cài và tự hết hạn — nên rò rỉ có bán kính ảnh hưởng hạn chế.
OAuth App xác thực bằng token truy cập người dùng lấy qua luồng OAuth chuẩn. Các token này mặc định dài hạn và hành động như người dùng — rò rỉ một cái nghĩa là kẻ tấn công làm được mọi điều người dùng đó làm được. Tài liệu GitHub đẩy bạn về phía GitHub App cho tích hợp mới một phần vì lý do này.
Quyền: hẹp vs rộng
GitHub App cho bạn xin quyền chi tiết: đọc issues, ghi checks, đọc pull requests, không truy cập gì khác. Mỗi quyền độc lập. Người dùng thấy danh sách chính xác và có thể từ chối.
OAuth App dùng hệ thống dựa trên scope cũ hơn: repo, read:user, v.v. Scope thô hơn. Scope repo cấp quyền đọc và ghi cho mọi repository người dùng thấy được — không có phiên bản "chỉ đọc trên repo cụ thể".
Với một bot review code chỉ cần đọc code và ghi check runs, một GitHub App với hai quyền cụ thể ít xâm phạm hơn nhiều so với OAuth App xin quyền repo đầy đủ.
Kiểm thử cục bộ cả hai
Cơ chế chữ ký webhook giống hệt — xem thiết lập tại kiểm thử webhook GitHub cục bộ. Khác biệt là cách bạn đăng ký URL.
- GitHub App: đặt URL webhook trong trang cài đặt của app. Cài app lên một repository thử nghiệm. Kích hoạt sự kiện. Xong.
- OAuth App: bản thân app không có webhook. Thêm một webhook repository (thủ công trong trang cài đặt repo, hoặc qua API) trỏ tới URL tunnel của bạn.
Với OAuth App, bạn cũng cần kiểm thử chính luồng callback OAuth — xem cách kiểm thử callback OAuth cục bộ.
Di chuyển giữa hai loại rất đau
Nếu bạn bắt đầu bằng OAuth App rồi sau nhận ra cần GitHub App, bạn không thể di chuyển. Người dùng phải ủy quyền lại app mới, bạn phải cấp lại mọi token đã lưu, và bất kỳ webhook repository nào bạn thiết lập qua OAuth App sẽ vẫn bắn cho tới khi bị xóa. Hãy dành mười phút lúc đầu để chọn đúng loại.
Khi nào chọn loại nào
Chọn GitHub App khi:
- Tích hợp của bạn chạy theo lịch riêng hoặc phản ứng với sự kiện, không có người dùng đăng nhập.
- Bạn muốn quyền hẹp trên các repository hoặc organization cụ thể.
- Bạn muốn webhook gắn với phạm vi cài đặt, không phải cấu hình theo từng repo.
- Bạn đang xây thứ gì đó rốt cuộc sẽ lên GitHub Marketplace.
Chọn OAuth App khi:
- Công cụ của bạn là một UI mà người dùng đăng nhập và làm việc trong chính tài khoản GitHub của họ.
- Bạn cần hành động chính xác như người dùng, gồm cả mẫu truy cập của họ.
- Bạn không cần webhook, hoặc sẽ thiết lập thủ công theo từng repo.
Về chi tiết xác minh chữ ký nền tảng, xem hướng dẫn xác minh chữ ký. Tham gia danh sách chờ của PortPreview để có một tunnel xử lý được timing webhook của GitHub và bắt để phát lại.