paint-brush
Nhưng, Nhưng, Nhưng Thật Sự Là HaaRrRrRrRrRdtừ tác giả@dbozhinovski
511 lượt đọc
511 lượt đọc

Nhưng, Nhưng, Nhưng Thật Sự Là HaaRrRrRrRrRd

từ tác giả Darko Bozhinovski8m2024/08/19
Read on Terminal Reader

dài quá đọc không nổi

Không, không phải vậy. Nó nhàm chán, rườm rà, là một vấn đề đã được giải quyết... nhưng đừng gọi nó là khó như một tuyên bố chung chung.
featured image - Nhưng, Nhưng, Nhưng Thật Sự Là HaaRrRrRrRrRd
Darko Bozhinovski HackerNoon profile picture


Không, không phải vậy. Nó nhàm chán, rườm rà, là một vấn đề đã được giải quyết... nhưng đừng gọi nó là khó như một tuyên bố chung chung.


Tôi đã "sử dụng MD5 để băm mật khẩu trong PHP" nhiều năm rồi. Chắc chắn, đó là một ý tưởng tồi tệ, ngay cả vào năm 2012. Nhưng, vào thời điểm đó, tôi không nhớ đã coi auth là "khó". Bản thân nó đã là một thử thách khá đơn giản - lấy email hoặc tên người dùng, lấy mật khẩu, băm nó (với MD5, như "ý định của Chúa"), và nếu bạn đặc biệt có ý thức bảo mật, [ muối ] mật khẩu. Lưu trữ tất cả những thứ đó ở đâu đó, thường là trong cơ sở dữ liệu. Ta-da, đăng ký xong.


Ngày nay, câu chuyện đã thay đổi. "Xác thực khó" có vẻ như là một câu chuyện luôn hiện hữu chỉ cách một cú nhấp chuột trên HackerNews hoặc Reddit. Nhưng thực sự có phải vậy không? Theo tôi, sự thật là, xác thực không khó để xây dựng - bất kỳ ai cũng có thể học (và mọi người trong lĩnh vực này đều nên học những điều cơ bản). Thách thức thực sự nằm ở các phần bổ sung: MFA, quản lý người dùng, đặt lại mật khẩu, mỗi nhà cung cấp OAuth trong số hàng trăm nhà cung cấp và hợp nhất tài khoản từ các nhà cung cấp khác nhau. Nó giống như cái chết của hàng ngàn vết cắt. Vì xác thực là một vấn đề đã được giải quyết, nên việc phát minh lại bánh xe không phải là cách sử dụng thời gian tốt nhất của bạn. Nhưng điều đó không có nghĩa là "xác thực khó" như một tuyên bố chung chung là đúng hoặc thậm chí gần đúng. Bạn nên thử nghiệm, hiểu những điều cơ bản và xây dựng từ đó. Độ phức tạp chỉ tăng lên theo quy mô (hoặc quy mô tiềm năng) của những gì bạn đang tạo ra.


Vậy, xác thực thực sự khó đến mức nào? Chúng ta hãy cùng tìm hiểu sâu hơn.


Ngày xưa...

Tiếp tục câu chuyện về PHP và md5, việc xây dựng chức năng đăng nhập tuân theo một loạt các bước tương tự; Lấy email và mật khẩu, kiểm tra xem email có trong bộ lưu trữ của bạn không, băm mật khẩu cùng với salt được lưu trữ cho email đó, so sánh giá trị băm kết quả với giá trị băm được lưu trữ trong cơ sở dữ liệu và nếu mọi thứ hoạt động tốt, hãy đặt cookie thông qua setcookie (chúng ta vẫn đang ở trong thế giới PHP - không phải là logic tổng thể quá khác biệt trong các hệ sinh thái khác).


Đăng xuất thậm chí còn đơn giản hơn - chỉ cần vô hiệu hóa cookie trên máy chủ và bạn đã hoàn tất. Nếu máy chủ không thấy cookie với yêu cầu tiếp theo, bạn sẽ không đăng nhập. Vì vậy, việc thực hiện các tuyến đường được xác thực cũng là một thử thách đơn giản nói chung. Mọi thứ có thể trở nên rắc rối khi nói đến quyền, nhưng thường thì với các ứng dụng tôi phải xây dựng, chúng tôi chỉ có quản trị viên và người dùng. Đó là thứ bạn có thể dễ dàng lưu trữ cùng với bản ghi người dùng hoặc trong bảng quyền nếu bạn cần mở rộng số lượng vai trò bạn có cho ứng dụng của mình.


Tiết lộ đầy đủ—Tôi làm việc cho SuperTokens . Tuy nhiên, bài viết này xuất phát từ sự thất vọng cá nhân về một câu chuyện phổ biến về việc xác thực khó khăn như thế nào như một tuyên bố chung. Nói cách khác, tôi không cố gắng "bán cho bạn thứ của tôi". Hãy sử dụng bất cứ thứ gì bạn thích.


Tự cuốn - một cách "hiện đại"

Email/mật khẩu và xác thực xã hội

Để đạt được những gì chúng ta đang có ngày hôm nay, chúng ta sẽ bắt đầu từ đầu... Thật ngạc nhiên, tôi biết. Có lẽ chúng ta có thể đồng ý rằng những thành phần này đủ để tạo ra một PoC email/mật khẩu + đăng nhập xã hội:


  1. Máy chủ xử lý các tuyến đường - đăng ký, đăng nhập, đăng xuất...
  2. Một số loại lưu trữ để lưu giữ hồ sơ người dùng (một mảng trong bộ nhớ cũng có tác dụng)
  3. Lượt xem - màn hình đăng nhập, đăng ký và "bảng điều khiển" đã xác thực.
  4. Trình xử lý xác thực xã hội


Đi với Express và Passport, vì chúng ta không phát minh lại bánh xe, chúng ta sẽ có đúng 150 dòng mã rất, rất nhàm chán và lặp đi lặp lại: https://github.com/supertokens/auth-express/blob/master/index.mjs . Phần tiếp theo sẽ là phần giải thích sơ lược về những gì đang diễn ra trong mã, vì vậy hãy thoải mái bỏ qua nếu bạn đã quen thuộc với các khái niệm. Dù sao thì ứng dụng Express cũng là PoC.


Chúng ta hãy nhanh chóng phân tích nó:

Hiển thị nội dung trên màn hình

Theo cách tôi thấy, có hai cách để tiếp cận vấn đề này - bắt đầu bằng việc render và chuyển sang tuyến xác thực hoặc ngược lại. Chủ yếu là do tình cờ, tôi trở thành một người dùng FE nặng (tôi vẫn có thể làm SQL, trong trường hợp bạn thắc mắc), vì vậy tôi sẽ bắt đầu bằng cách tiếp cận "rendering stuff on screen".


Vì đây là PoC, chúng ta sẽ không sử dụng React-fancy. SSR thông thường với ejs sẽ ổn: https://github.com/supertokens/auth-express/tree/master/views

Thêm tuyến đường

Dựa trên một số ví dụ về passport.js nhưng được đơn giản hóa hơn, chúng ta cần những điều sau:

  1. Một số phụ thuộc: npm i passport passport-local express-session . Chúng ta hãy cùng xem qua từng phụ thuộc:

    1. Passport.js - phần mềm trung gian xác thực ban đầu cho express và node.
    2. passport-local - một chiến lược xác thực cho Passport; Một chiến lược xác thực trong mô-đun xử lý quy trình xác thực cho một phương thức xác thực cụ thể - trong trường hợp này, là đăng nhập cục bộ bằng tên người dùng (email) và mật khẩu.
    3. express-session - một phần mềm trung gian quản lý dữ liệu phiên, cho phép bạn lưu trữ và duy trì các phiên người dùng giữa các yêu cầu HTTP. Nó hoạt động bằng cách chỉ định một ID phiên duy nhất cho mỗi máy khách, được lưu trữ trong cookie ở phía máy khách và được sử dụng để truy xuất dữ liệu phiên trên máy chủ.
  2. Nơi lưu trữ người dùng của chúng tôi (ví dụ được liên kết ở trên sử dụng một mảng trong bộ nhớ): https://github.com/supertokens/auth-express/blob/master/index.mjs#L13

  3. Cấu hình cho phiên bản hộ chiếu và phiên bản LocalStrategy của chúng tôi để xử lý các yêu cầu đến để tra cứu người dùng: https://github.com/supertokens/auth-express/blob/master/index.mjs#L18

  4. Khởi tạo hộ chiếu ( https://github.com/supertokens/auth-express/blob/master/index.mjs#L60 ) và express-session ( https://github.com/supertokens/auth-express/blob/master/index.mjs#L69 ).


Dài dòng, chắc chắn rồi. Khó? Tôi không nghĩ vậy, ít nhất là không theo nghĩa thực hiện như một món đồ chơi. Nhưng chúng ta đã vượt qua việc sử dụng kết hợp email/mật khẩu một thời gian trước. Hãy cùng xem xét xem việc thêm một nhà cung cấp dịch vụ xã hội vào những gì chúng ta có khó như thế nào.


Đối với một nhà cung cấp ví dụ ở đây, tôi quyết định chọn GitHub vì một lý do đơn giản—nếu bạn quyết định theo dõi toàn bộ, thì đây là một trong những nhà cung cấp dễ bắt đầu nhất (như Google vậy).


Nếu bạn quyết định theo dõi đầy đủ, đây là liên kết mô tả cách lấy các khóa GitHub đó: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app À, nhân tiện, những khóa trong kho lưu trữ không hợp lệ, trong trường hợp bạn lo lắng ;)

Tích hợp GitHub OAuth2 vào PoC của chúng tôi

Trước hết, chúng ta cần thêm một sự phụ thuộc nữa, npm i passport-github2 . passport-github2 là một chiến lược xác thực cho Passport, cho phép chúng ta tích hợp với API OAuth2 của GitHub.


Một số trình xử lý ( https://github.com/supertokens/auth-express/blob/master/index.mjs#L122-L133 ) và cấu hình ( https://github.com/supertokens/auth-express/blob/master/index.mjs#L29-L45 ) sau đó, vậy là xong. Phức tạp ư? Có lẽ là không. Quan liêu ư? Chắc chắn rồi. Nhàm chán ư? Chắc chắn rồi. Đặc biệt là nếu bạn phải làm đi làm lại nhiều lần. Đây là một vấn đề đã được giải quyết; phát minh lại bánh xe thường không phải là cách sử dụng thời gian tốt nhất như chúng ta đã xác định.


Ý tưởng lớn

Đến giờ, có lẽ chúng ta có thể đồng ý rằng Auth không khó để xây dựng . Do đó, nó không phải là thứ ma thuật mà chỉ những phù thủy râu trắng nói được ngôn ngữ huyền bí của JWT mới có thể hiểu và thực hiện được.


Không, thực tế là, tôi cho rằng với tư cách là một nhà phát triển, người ta nên hiểu những điều cơ bản nhất về cách thức hoạt động của auth. Và tôi thường thấy một câu chuyện khẳng định ngược lại - đại loại như "tin tôi đi, anh bạn, chúng tôi có thể xử lý việc đó cho anh". Và chắc chắn, tôi đồng ý rằng phần lớn, việc tự tạo auth là lãng phí thời gian. Nhưng nó không khó để xây dựng và chắc chắn không phải là điều gì đó huyền bí. Nơi thực sự trở nên rắc rối là với mọi thứ xung quanh auth và trải nghiệm của người dùng.


Hãy xem xét điều này - trong ví dụ trên, chúng ta có một thứ auth đang hoạt động. Một loại. Nhưng đây là những gì nó không thể làm (cũng được đề cập trong phần mở đầu bài viết):

  • 2FA, MFA
  • Đặt lại mật khẩu
  • Mỗi nhà cung cấp OAuth trong số hàng trăm nhà cung cấp có đặc điểm riêng
  • Quản lý người dùng
  • Tài khoản được hợp nhất từ các nhà cung cấp khác nhau
  • Bao gồm tất cả các trường hợp ngoại lệ có thể xảy ra và các lỗ hổng bảo mật tiềm ẩn
  • ...và tôi có thể tiếp tục


Có lẽ chúng ta có thể triển khai từng phần này. Và riêng lẻ, mỗi phần có thể được coi là đơn giản. Nhưng chúng cộng lại. Vì vậy, không nhất thiết là việc triển khai—mà là việc duy trì, chịu trách nhiệm về nó, cập nhật các tiêu chuẩn, vi phạm bảo mật, v.v. Thêm vào đó, hãy giơ tay—có bao nhiêu người trong số các bạn thích đọc RfC? Tôi không nghĩ mình sẽ thấy nhiều người giơ tay nếu chúng ta đang họp mặt.


Ý tôi là xác thực không dễ dàng, xét trên tổng thể. Chắc chắn, chúng ta có thể dễ dàng ghép lại với nhau thành PoC, như chúng ta đã làm ở trên. Nhưng nó không phải là phép thuật, không phải là không thể hiểu được, và làm ơn, làm ơn đừng nói rằng nó là phép thuật. Theo tôi, lối suy nghĩ đó (và tiếp thị) đang gây tổn hại cho toàn bộ ngành.


Vì vậy, câu hỏi tiếp theo tự nhiên sẽ là - khi nào bạn nên tự làm?

Dự án đồ chơi, indie và hoạt động giáo dục

...bằng mọi cách. Tôi thậm chí còn khuyến khích điều đó. Bạn học được nhiều điều khi làm, vậy tại sao không? Nếu dự án indie/đồ chơi hoặc blog của bạn phát triển và có lượng người dùng hoặc người theo dõi đáng kể, hãy chuyển sang dịch vụ, giải pháp tự lưu trữ hoặc thứ gì đó khác. Sau cùng, bạn đã có sản phẩm tại thời điểm đó và chắc chắn bạn sẽ dành thời gian xây dựng sản phẩm đó tốt hơn là duy trì xác thực.

Khởi nghiệp

Nói chung, nếu bạn đang xây dựng sản phẩm, đừng tự tạo ra xác thực của riêng bạn. Nó giống như việc phát minh lại một bánh xe rất nhàm chán và rườm rà. Bạn có rất nhiều lựa chọn để lựa chọn. Thêm vào đó, bạn đang xây dựng một cái gì đó, đúng không? Tại sao chúng ta lại có cuộc trò chuyện này nếu sản phẩm của bạn không phải là xác thực?

Scaleups trở lên (tuy nhiên chúng tôi chọn cách định nghĩa chúng)

Đừng. Cùng lý do như với các công ty khởi nghiệp - nhưng chắc chắn điều này đúng hơn ở đây.


Bạn có thể thấy tôi đang muốn nói đến điều gì. "Auth is hard" là, theo tôi, một lời chào hàng tiếp thị khi được sử dụng như một tuyên bố chung. Bạn có thể hiểu auth, bạn có thể xây dựng nó, nhưng nó nhàm chán, không thú vị khi duy trì, và đó là một vấn đề đã được giải quyết. Do đó, nó có thể được coi là một mặt hàng - một mặt hàng mà bạn có thể lấy ra khỏi kệ với bất kỳ hương vị nào bạn chọn (một số tùy chọn bên dưới).

Bối cảnh tự lưu trữ và FOSS

Đối với những người muốn sở hữu một chồng tiền (như tôi), bạn cũng có rất nhiều lựa chọn:

Thư viện xác thực

  • Passport.js, được đề cập chi tiết ở trên
  • Lucia - Một thư viện xác thực đơn giản và linh hoạt dành cho các ứng dụng web hiện đại, tập trung vào trải nghiệm của nhà phát triển và tính dễ sử dụng.
  • Auth.js - Một thư viện xác thực nhẹ và có thể tùy chỉnh cho Node.js, được thiết kế để dễ dàng tích hợp vào nhiều khuôn khổ và ứng dụng khác nhau. Bắt đầu là một thư viện cho Next.

Máy chủ xác thực

  • Keycloak - Máy chủ quản lý danh tính và truy cập nguồn mở cung cấp các tính năng như đăng nhập một lần (SSO), môi giới danh tính và liên kết người dùng.
  • SuperTokens (xem tuyên bố từ chối trách nhiệm ở trên) - Một giải pháp xác thực nguồn mở cung cấp các tính năng được xây dựng sẵn như quản lý phiên, đăng nhập bằng mạng xã hội và xác thực email/mật khẩu với trọng tâm là bảo mật và đơn giản.
  • FusionAuth - Một nền tảng xác thực linh hoạt dành cho nhà phát triển, cung cấp các tính năng như quản lý người dùng, xác thực đa yếu tố (MFA) và đăng nhập một lần (SSO).
  • Authelia - Máy chủ xác thực mã nguồn mở cung cấp xác thực đa yếu tố (MFA) và SSO, được thiết kế để bảo mật các ứng dụng bằng cách sử dụng proxy ngược.

Lưu trữ + Xác thực

  • Supabase - Nền tảng dịch vụ phụ trợ (BaaS) mã nguồn mở cung cấp cơ sở dữ liệu, xác thực và khả năng thời gian thực, được thiết kế như một giải pháp thay thế cho Firebase.
  • Pocketbase - Giải pháp nguồn mở kết hợp cơ sở dữ liệu, xác thực và lưu trữ tệp, nhằm mục đích đơn giản hóa quá trình phát triển các ứng dụng web và di động hiện đại.


Vì vậy, ngay cả khi bạn không muốn sử dụng phần mềm của bên thứ ba cho Auth, bạn vẫn có thể chọn một phần mềm nguồn mở có sẵn tùy theo nhu cầu và sở thích của mình và sử dụng.

Điểm mấu chốt: xác thực là "thủ tục quan liêu" của dev

"Điểm mấu chốt" của tôi là tránh phát minh lại bánh xe, đặc biệt là nếu đó là một vấn đề đã được giải quyết, như auth. Hãy tìm hiểu về những chiếc bánh xe đó, thử nghiệm với chúng, chế tạo một chiếc bánh xe đồ chơi và hiểu nó. Nhưng làm ơn, làm ơn, đừng bán nó như một thứ khó hiểu và khó chế tạo đến mức không thể. Hãy giáo dục, đừng kiểm soát.