3 điểm bởi GN⁺ 17 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Val Town đã rời Supabase vào năm 2023, chuyển cơ sở dữ liệu sang Render và xác thực sang Clerk, nhưng thấy kiến trúc đẩy trách nhiệm về người dùng và phiên ra bên ngoài là không phù hợp, nên đã chuyển sang Better Auth cách đây một tháng
  • Clerk từng đề xuất loại bỏ bảng người dùng, nhưng vì có tính năng xã hội nên Val Town thường xuyên phải hiển thị nội dung, tên người dùng và ảnh đại diện của nhiều người dùng; do giới hạn API và việc đồng bộ với Clerk, về thực chất họ phải vận hành hai bảng người dùng với độ phức tạp cao
  • Việc Clerk đảm nhận cả làm mới phiên đã biến nó thành điểm lỗi đơn lẻ; khi Clerk gặp sự cố, không chỉ đăng nhập/đăng xuất bị ảnh hưởng mà cả người dùng đã đăng nhập cũng khó sử dụng toàn bộ trang web; từ tháng 5/2025 trở đi, theo trang trạng thái, thời gian hoạt động mà họ cảm nhận được nằm đâu đó giữa 99% và 99,9%
  • Val Town không viết lại ngay vì SDK, tính năng quản trị, chống lạm dụng và dashboard của Clerk vẫn hữu ích, nhưng họ đặt ra nguyên tắc sẽ không còn tin tưởng quản lý phiên của bên thứ ba nữa
  • Better Auth phù hợp với yêu cầu nhờ chất lượng mã nguồn, tích hợp framework và lõi mã nguồn mở độc lập; trong khoảng 2 tuần, Val Town hỗ trợ đồng thời Clerk và Better Auth, chấp nhận hai loại cookie để dần dần di chuyển phiên

Bối cảnh chuyển đổi

  • Năm 2023, Val Town rời Supabase để chuyển sang cấu hình cơ sở dữ liệu truyền thống hơn, thay cơ sở dữ liệu bằng Render và phần xác thực bằng Clerk
  • Cuối năm 2023, đã có issue ghi nhận rằng họ cần rời Clerk, và issue đó được đóng khi họ chuyển sang Better Auth cách đây một tháng
  • Clerk và Supabase đều là các dịch vụ thành công, lần lượt gọi vốn 50 triệu USD100 triệu USD với định giá 5 tỷ USD, nhưng kiến trúc của Val Town lại xung đột mạnh với kỳ vọng của Clerk
  • Quá trình chuyển đổi có nhiều giải pháp vòng vo, lỗi và sự cố; đặc biệt, cấu trúc mà Clerk cố gắng thay thế cả bảng người dùng lẫn bảng phiên đã bộc lộ là vấn đề cốt lõi

Vấn đề cốt lõi: đưa bảng người dùng và bảng phiên ra bên ngoài

  • Vì sao khó dùng Clerk như bảng người dùng

    • Clerk đã mạnh mẽ khuyến khích hướng loại bỏ bảng người dùng qua bài viết năm 2021 “Consider dropping your users table” và video năm 2023 “DELETE your Users table”
    • Khi chuyển đổi ban đầu, Val Town cho rằng họ có thể lấy dữ liệu như thiết lập người dùng, URL avatar hay email từ Clerk API mỗi khi cần
    • Trong Clerk SDK, rootAuthLoader có tùy chọn loadUser để tải dữ liệu người dùng trong khi xử lý xác thực toàn ứng dụng, và nó hoạt động tốt trong môi trường phát triển
    • Ở production, giới hạn của endpoint đó là 5 request mỗi giây tính trên toàn bộ tài khoản và tổng tất cả người dùng; vấn đề này về sau được giải quyết bằng việc bỏ tùy chọn này
    • Với các dịch vụ có tính năng xã hội như Val Town, nhiều trang cần hiển thị nội dung, tên người dùng và avatar của những người dùng khác, nên giả định trong UI mặc định của Clerk rằng người dùng chỉ đọc avatar và thiết lập của chính mình từ JWT là không phù hợp
    • Lời khuyên từ phía Clerk là đồng bộ avatar và các thông tin khác giữa Clerk và bảng người dùng của Val Town, dẫn đến việc nguồn chân lý của cùng một dữ liệu bị chia làm hai nơi và tạo ra độ phức tạp của việc vận hành hai bảng người dùng
  • Độ phức tạp của luồng đăng ký do đồng bộ bằng webhook tạo ra

    • Để đồng bộ dữ liệu Clerk vào cơ sở dữ liệu của Val Town, họ phải dùng webhook, khiến quy trình đăng ký trở nên phức tạp và mong manh
    • Trong một khoảng ngắn ngay sau khi đăng ký, người dùng có thể có tài khoản Clerk nhưng chưa có dòng dữ liệu trong cơ sở dữ liệu của Val Town
    • Vì Val Town bắt buộc phải có tên người dùng, cũng có thể xảy ra trạng thái người dùng đã có tài khoản Clerk và dòng trong cơ sở dữ liệu nhưng tài khoản vẫn chưa hoàn tất
    • Thiết lập người dùng phải bị chia tách thành các mục do Clerk quản lý như phương thức xác thực và các mục Val Town cần như tên người dùng hay thiết lập editor

Cấu trúc phiên khiến Clerk trở thành điểm lỗi đơn lẻ

  • Phiên người dùng dựa trên cookie thường có thời gian sống ngắn và được làm mới liên tục để có thể vô hiệu hóa nhanh
  • Trong cấu trúc này, cứ vài phút người dùng lại phải đổi cookie phiên sang cookie mới, và subdomain của Val Town sẽ chuyển tiếp yêu cầu tới Clerk để xử lý việc làm mới
  • Val Town không có bảng phiên và cũng không chịu trách nhiệm về phiên
  • Cách làm này phù hợp nếu muốn tránh gánh trách nhiệm xác thực, nhưng khi Clerk ngừng hoạt động thì không chỉ đăng nhập và đăng xuất hỏng, mà ngay cả người dùng đã đăng nhập cũng không thể sử dụng toàn bộ trang web
  • Clerk gặp sự cố khá thường xuyên và kéo dài; theo trang trạng thái từ tháng 5/2025 trở đi, thời gian hoạt động mà họ cảm nhận được nằm giữa 99% và 99,9%
  • Độ tin cậy của một hệ thống phức tạp bị ràng buộc bởi giá trị nhỏ nhất trong độ tin cậy kết hợp của các thành phần quan trọng
  • Ngoài hai vấn đề lớn này còn có nhiều lỗi và vấn đề khác liên quan đến Clerk; đa số cuối cùng đều được sửa, nhưng họ phải vật lộn với “Stale Issue Bot” vốn tự động đóng issue

Vì sao không chuyển ngay

  • Công việc kiểu “chuyển từ X sang Y” có thể làm chậm tốc độ phát triển và ảnh hưởng đến sự ổn định tinh thần của cả nhóm, nên Val Town cố tránh viết lại nếu chưa thật sự cần thiết
  • Clerk cung cấp SDK cho các công nghệ mà Val Town dùng như Remix, Fastify và Express, đồng thời theo kịp các thay đổi của những framework này khá tốt
  • Các tính năng quản trị và chống lạm dụng của Clerk giúp xử lý các vấn đề hỗ trợ khách hàng và ngăn chặn người dùng gian lận
  • Lĩnh vực Clerk đặc biệt phù hợp là các ứng dụng tương đối đơn giản, thiên về frontend, không có yếu tố xã hội và không cần bảng người dùng
  • Việc bắt đầu rất dễ và mức giá cũng chấp nhận được, còn dashboard của Clerk cũng khá tốt
  • Không có nhiều lựa chọn thay thế cho xác thực, và trong các giải pháp xác thực mã nguồn mở thì nhiều cái đã cũ và gần như bị bỏ bê
  • Các nền tảng xác thực dạng dịch vụ có rủi ro nhà cung cấp, và các vấn đề giống Clerk có thể lặp lại
  • Val Town không muốn tự xây xác thực từ đầu để rồi lộ ra các lỗ hổng mới và đáng xấu hổ, nhưng cũng không muốn giao quá nhiều trách nhiệm cho nhà cung cấp
  • Đặc biệt, họ hình thành nguyên tắc là sẽ không còn tin tưởng vào quản lý phiên của bên thứ ba nữa

Cách chọn Better Auth và phương thức chuyển đổi

  • Better Auth đáp ứng được nhiều điều kiện nhờ chất lượng mã nguồn cao, tích hợp tốt với nhiều framework và là một dự án mã nguồn mở độc lập đủ khả năng dùng thực tế
  • Better Auth cũng vẫn là một codebase lớn và phức tạp chủ yếu do một công ty phát triển, nên rủi ro nhà cung cấp vẫn còn
  • Tuy vậy, sự phụ thuộc vào việc một bên thứ ba phải luôn online để phiên và xác thực người dùng hoạt động đã biến mất
  • AuthKit của WorkOS cũng là một ứng viên rất mạnh và rất mượt, nhưng sau khi đã đi qua hai nhà cung cấp, một giải pháp có thể hoạt động độc lập với lõi mã nguồn mở trở nên quan trọng hơn
  • Dashboard và các add-on trả phí của Better Auth cũng phù hợp với nhu cầu của Val Town
  • Val Town tự quản lý toàn bộ dữ liệu, và plugin sẽ cung cấp API trên trang Val Town để dashboard của Better Auth lấy thông tin và thực hiện quản lý người dùng ở mức nhẹ
  • Dịch vụ trả phí “Infrastructure” của Better Auth, theo cách Val Town sử dụng, về thực chất gần như stateless và không tham gia vào quản lý phiên
  • Trong thời gian chuyển đổi, họ hỗ trợ đồng thời Better Auth và Clerk trong khoảng 2 tuần
  • Mọi endpoint xử lý xác thực đều chấp nhận cả hai loại cookie, và trang đăng nhập cung cấp phiên Better Auth để người dùng dần dần chuyển sang Better Auth
  • Vì đây là công việc liên quan đến bảo mật, họ phải đọc kỹ, viết lại và kiểm thử toàn bộ mã; phần mã xác thực Better Auth thuần cuối cùng đều do họ tự viết
  • Better Auth cũng phù hợp với Vals; nếu muốn thêm xác thực vào mã Val Town, có thể dùng Better Auth starter template

Bài học còn lại

  • Thời gian hoạt động của nhà cung cấp upstream ảnh hưởng trực tiếp đến thời gian hoạt động của dịch vụ, nên cần đánh giá cẩn thận mức độ phơi nhiễm với rủi ro đó
  • Dù một sản phẩm có thể phù hợp với nhiều trường hợp sử dụng và thành công lớn, nó vẫn có thể không phù hợp với một bài toán cụ thể
  • Môi trường phần mềm thay đổi rất nhanh, và một giải pháp phù hợp từng chưa tồn tại có thể xuất hiện sau một năm khi bạn thực sự cần đến nó

1 bình luận

 
Ý kiến trên Hacker News
  • Tôi muốn ai đó thông minh hơn tôi giải thích vì sao lại phải giao bảng users của Postgres cho một nhà cung cấp bên thứ ba
    Tôi không hiểu việc tự duy trì bảng đó trên một VM Hetzner thì có gì khó đến thế. Đây đâu phải thanh toán, chỉ là dữ liệu với vài trường mà thôi

    • Khi chỉ là vài trường thì đúng vậy, nhưng chẳng mấy chốc nó sẽ không còn đơn giản nữa
      Bạn sẽ phải gắn thêm SSO, SAML, SCIM, OIDC, OAuth, xác thực hai yếu tố, xác thực không mật khẩu, token xác minh v.v., và với mỗi tính năng lại cần những kiểu tích hợp biến thể với các hệ thống phổ biến. Ở công ty chúng tôi, đã có một thời gian một nửa thời gian của đội kỹ sư hỗ trợ bị tiêu tốn vào việc xử lý đủ loại vấn đề SSO của hệ thống xác thực tự xây
    • Tôi cũng khó hiểu tương tự. Tôi luôn tự hỏi vì sao thứ như Supabase lại tồn tại, và nó có vẻ cho thấy thế giới phát triển frontend đã đi xa đến mức nào khỏi cách làm vốn có thể đơn giản và an toàn hơn về cơ bản
    • Bạn không muốn nâng cấp sự nghiệp lên làm kiến trúc sư sao? Vẽ một cái hộp rồi đặt tên User Management, sau đó gắn một SaaS như Clerk vào là có thể giả định nó đã được quản lý
      Thế là mọi yêu cầu mà bạn cảm thấy “tự mình triển khai cũng chẳng tạo ra giá trị gì” đều có thể bị đẩy vào cái hộp đen ma thuật đó
    • Mọi người rất sợ làm hỏng phần xác thực rồi bị hack. Vì vậy họ có xu hướng đẩy trách nhiệm đó sang bên thứ ba và không muốn bận tâm nữa
    • Tôi cũng thấy bối rối y hệt. Nhìn chung, nếu yêu cầu không quá rộng thì tự vận hành cơ sở dữ liệu và quản lý xác thực bằng thứ như Django còn dễ hơn
      Ở quy mô doanh nghiệp thì có thể sẽ khác
  • Tôi là Bereket của Better Auth. Chính để giải quyết vấn đề này mà tôi bắt đầu Better Auth, rồi sau đó nó trở thành công ty
    Luôn rất vui khi thấy người khác cũng nhận được cùng giá trị đó. Vẫn còn rất nhiều việc phải làm, nên tôi rất muốn biết có thể cải thiện điều gì

    • Không biết có kế hoạch hỗ trợ backend Python không. Hoặc liệu hiện giờ đã có cách nào để chúng tôi dùng được chưa
    • Bạn có cho rằng lý do xác thực trên trình duyệt phức tạp là vì trình duyệt không làm đủ nhiều việc không?
  • Còn tệ hơn cả câu “bài học khó khăn khi xây một hệ thống phức tạp là độ tin cậy của nó bằng với mức thấp nhất trong các thành phần cốt lõi”
    Thực tế, độ sẵn sàng tổng thể bằng tích độ sẵn sàng của mọi thành phần nằm trên đường đi quan trọng. Nếu phần mềm, lớp xác thực và nhà cung cấp đám mây đều có độ sẵn sàng 99%, và chỉ cần một trong ba cái chết là dịch vụ sập, thì độ sẵn sàng cuối cùng chỉ còn 97%. Nếu có 11 thành phần như vậy thì bạn sẽ chẳng còn nổi một “số 9” nào trong độ sẵn sàng. Vì vậy việc giảm bớt thành phần và chọn giải pháp đáng tin cậy hơn là rất quan trọng, và tôi mừng vì đội này đã chọn con đường đó

    • Tôi đã học bài này theo cách khó chịu trong đợt sự cố Cloudflare lớn lần trước. Dù tôi không dùng Cloudflare, khóa công khai Auth0 để xác minh JWT lại được phục vụ phía sau Cloudflare, nên toàn bộ chuỗi xác thực bị gãy và ứng dụng của tôi bị tê liệt trong vài giờ
  • Tôi cũng đã đọc rất thích bài viết trước đây về việc di chuyển khỏi Supabase (https://blog.val.town/blog/migrating-from-supabase)
    Những bài viết thẳng thắn, chất lượng về các quyết định kỹ thuật dài hạn còn quá ít, mong bạn tiếp tục viết blog

  • Gần đây tôi đã trải qua một hành trình tương tự. Tôi bắt đầu với Stack Auth, nhưng vì giới hạn tốc độ cực kỳ khắt khe và hiệu năng tệ nên không thể dùng trong production; ngay cả khi không bị dính rate limit thì nó vẫn chậm
    Sau đó tôi chuyển sang WorkOS AuthKit và nó hoạt động tốt hơn nhiều, đồng thời hỗ trợ cả những tính năng doanh nghiệp hữu ích. Dù vậy, nếu là dự án mới thì tôi vẫn nghiêng về Better Auth. Việc đồng bộ trạng thái giữa nhà cung cấp xác thực bên ngoài và trạng thái người dùng của tôi là ổ lỗi kinh điển, và việc giữ ít trạng thái nhất có thể ở nhà cung cấp xác thực sẽ giúp ích, nhưng vẫn còn sót lại một phần. Việc làm mới JWT access token mỗi vài phút cũng là một ổ lỗi khác, và nếu tự kiểm soát xác thực thì thành thật mà nói chẳng cần làm vậy. WorkOS không có API hoàn chỉnh, và được xây dựng trên giả định mỗi tài khoản trả phí chỉ có một sản phẩm cùng số lượng môi trường cố định (staging, production, và nếu yêu cầu hỗ trợ thì thêm một cái nữa). Những thứ như redirect URL cũng phải được đưa vào danh sách cho phép trong dashboard, và có vẻ không có cách nào để agent xử lý dễ dàng. Tôi không thấy việc thuê ngoài xác thực là hợp lý. Càng chia nhỏ trạng thái ra ít dịch vụ thì càng ít vấn đề. Có những trường hợp không tránh khỏi như thanh toán, hoặc cần cơ sở dữ liệu chuyên biệt vì hiệu năng, nhưng với xác thực thì nếu đã có thư viện tốt, thực sự không có lý do gì để làm vậy. Người ta cũng nói dùng dịch vụ sẽ giúp bắt đầu nhanh hơn, nhưng các vấn đề tôi gặp với dịch vụ xác thực không liên quan đến quy mô lớn, và phần lớn đã nổ ra từ trước khi phát hành

  • Tôi đang dùng Clerk và khá không hài lòng. Nó không có RBAC tử tế
    Vai trò bị gắn với tổ chức chứ không phải với chính người dùng, nên không thể có khái niệm như quản trị viên toàn cục, và phải lách bằng cách lưu các cặp khóa-giá trị tùy ý trong metadata. Trong vài tuần, vài tháng gần đây cũng đã có nhiều lần downtime, và mỗi lần như vậy là toàn bộ ứng dụng đều hỏng. Tôi sẽ phải suy nghĩ rất kỹ nếu dùng lại trong tương lai

  • Tôi thực sự thấy may vì đã chọn Lucia từ sớm. Thư viện này về cơ bản đã kết thúc, và thay vào đó là tài liệu cùng các tiện ích nhỏ để giúp bạn tự quản lý và tự host phần xác thực
    Xác thực lúc nào cũng được mô tả như một thứ to lớn, đáng sợ, vượt ngoài khả năng tự quản lý, nhưng sau khoảng một tuần học cách bảo mật và salting cơ bản hoạt động ra sao, tôi thấy tự tin hơn rất nhiều về toàn bộ cơ chế vận hành

    • https://lucia-auth.com/
      Tôi nhớ khi họ loại bỏ thư viện và biến nó thành tài liệu học cách tự triển khai xác thực từ đầu. Đó là một quyết định tuyệt vời, và tôi rất tôn trọng tác giả
  • Có thể nói việc so sánh Clerk với Better Auth gần như là không công bằng. Một bên là dịch vụ, một bên là thư viện, nên giống như so táo với cam
    Mọi dịch vụ bên thứ ba được tích hợp vào stack đều tạo thêm gánh nặng trách nhiệm, thư viện cũng vậy nhưng ở mức thấp hơn. Đã đến lúc nhiều dịch vụ được thay thế bằng thư viện hơn, và Better Auth cho thấy rất rõ cách tiếp cận đó. Tôi thích việc nó là một thư viện tích hợp vào frontend, backend và cơ sở dữ liệu

  • Bài của Tom lúc nào cũng đáng đọc
    Có ai còn nhớ Auth0passportjs không? Sự thay đổi trong các dịch vụ xác thực là bất tận, nhưng có lẽ cũng không tránh được vì các tiêu chuẩn vẫn tiếp tục thay đổi

    • OAuth 2.xOIDC thì không thay đổi nhiều. Tôi vẫn dùng Passport.js cùng với Firebase