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.
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 đượ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:
Đ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ó:
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
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:
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:
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
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
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 ;)
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.
Đế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):
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?
...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.
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?
Đừ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).
Đố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
Máy chủ xác thực
Lưu trữ + Xác thực
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" 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.