Tất tần tật về Authenticate API - Áp dụng mọi nơi, mọi chỗ, mọi framework

Khi xây dựng một ứng dụng theo kiến trúc Microservice thì chắc chắn bạn sẽ phải làm việc và phải viết các API để tạo liên kết dữ liệu giữa server và client.

Để đảm bảo an toàn cho các API này thì chúng ta cần tiến hành thiết lập Authentication - hay xác thực người dùng cho chúng, đảm bảo rằng chỉ những User đang sử dụng và có tài khoản trong hệ thống mới được phép thao tác với API để tương tác với dữ liệu hệ thống.

Nếu bạn nào quên thì hãy thêm ngay vào đi, còn nếu bạn không biết làm thế nào thì sau đây tôi xin mạnh dạn đề xuất một số phương thức để thiêt lập Authentication cho các API, vì đây chỉ là một kỹ thuật nên bạn có thể áp dụng nó cho bất cứ ngôn ngữ hay framework nào.

HTTP Basic Auth

Basic Auth là một trong những phương pháp xác thực đơn giản nhất dựa vào tên đăng nhập và mật khẩu của người dùng. Kỹ thuật này sẽ cho phép gửi một Key có tên Authorization vào Header trên mỗi request gửi đến server, với value chính là mã hóa base64 của tên người dùng ghép với mật khẩu:

Header của request trông sẽ giống thế này:

GET / HTTP/1.1
Host: api.xyz.com
Authorization: Basic 8dg8rk40902jtasKAAG92nsgd

Lợi:

Đầu tiên thì đây là một kỹ thuật đơn giản, không cầu kỳ phức tạp và dễ triển khai mà không cần đến nhiều thuật toán lằng nhằng, nếu bạn là một dev Reactjs hoặc Vuejs, để gửi request đến server bạn chỉ cần dùng package axios sau đó setup lại header giống như trên là xong.

Hạn chế:

Điểm hại dễ thấy nhất của việc xác thực kiểu này chính là bạn cần có username và password của người dùng để tiến hành tạo chuỗi mã hóa. Về mặt lý thuyết thì chuỗi Base64 có thể bị decode nên dễ khiến tài khoản của người dùng bị lộ.

Hơn nữa với một ứng dụng triển khai trên nền tảng microservice thì bạn cần lưu lại username và password của người dùng đâu đó trong client, điều này lại khiến các thông tin nhạy cảm này dễ bị lộ thêm nữa.

Từ đó có thể thấy với một ứng dụng dạng nhỏ thì kiểu mã hóa này sẽ phù hợp hơn là ứng dụng lớn, có nhiều user.

API Key

API Key đương nhiên cũng là một trong những cách để xác thực khi API được gửi đến server nhưng nó lại không cần đến tài khoản hay mật khẩu của người dùng.

Kỹ thuật này hoạt động bằng cách gần tương tự như Basic Auth, nó cũng sẽ thêm một chuỗi mã hóa vào Header của các API gửi đi, phía server sẽ bắt lấy chuỗi này rồi so sánh để xem có phải user của hệ thống đang thực hiện truy cập hay không.

Chỉ khác điều là chuỗi mã hóa này không dựa trên username hay password của người dùng mà hoàn toàn được tạo ra bởi người code ứng dụng. Chuỗi này có thể được lưu cố định ở đâu đó trong server hoặc cũng có thể được tạo một cách tự động với mỗi user hoặc mỗi request gửi đến.

Ví dụ một request gửi kèm API key sẽ trông như thế này:

curl https://api.xyz.com/v1/blablabla \
     -H "Content-Type:application/json" \
     -H "X-Auth-Key:1234567893feefc5f0q5000bfo0c38d90bbeb"

Bạn có thể thấy X-Auth-Key là key của được thêm vào header với value của nó là một chuỗi mã hóa từ client gửi đi.

Lợi:

Về mặt này nó cũng gần tương tự với Basic Auth: dễ triển khai, dễ cài đặt. Nhưng điểm lợi hơn một chút đó là các API Key có thể được tạo ra mà không bị giới hạn số lượng và cũng rất dễ dàng để cung cấp cho những người có nhu cầu sử dụng ứng dụng.

Hạn chế:

Các API Key này thực tế chỉ cho biết request đang gửi đến đúng địa chỉ, request hợp lệ chứ không cho biết có phải một user của hệ thống đang thực hiện thao tác trên ứng dụng hay không, hay là request lậu?? 😕

Việc này có thể hạn chế khi ứng dụng được triển khai dưới mô hình Server to Server vì key được ẩn đi rồi, nhưng với mô hình Client - Server thì sẽ khiến key dễ bị lộ vì bạn bắt buộc phải lưu lại Key này phía client. Bất cứ ai có key này đều có thể thực hiện request đến hệ thống một cách dễ dàng.

OAuth Token Base Authentication

Kỹ thuật xác thực này dựa trên thực tế: Mỗi service cần truy cập ứng dụng sẽ nhận được một token được cung cấp bởi một bên thứ 3 (Còn bên thứ 3 nào thì lát nói sau), token này sẽ cung cấp cho request từ service đó quyền truy cập và các quyền được thao tác với hệ thống.

Quy trình làm việc sẽ diễn ra như sau:

  1. Người dùng truy cập vào hệ thống, nhập thông tin tài khoản các thứ
  2. Ứng dụng chuyển hướng người dùng đến một ứng dụng bên thứ 3, nơi sẽ cung cấp cho các request sau này của người dùng một Token key để có thể truy cập sau này
  3. Bên thứ 3 này bắt đầu yêu cầu bạn cho xin một số quyền với tài khoản của bạn, sau khi bạn đồng ý với các điều khoản thì bạn sẽ nhận được Token key rồi bạn tiếp tục được chuyển hướng về ứng dụng bằng một URL
  4. Token key này sau đó được lưu vào tài khoản của bạn hoặc trên client và sẽ được sử dụng cho những request sau này.

Token này sẽ được gửi kèm trong header dưới dạng sau:

GET /XYZ HTTP/1.1
Host api.xyz.com
Authorization: Bearer  <your-received-token>

Các token này hoàn toàn có thể thực hiện làm và cung cấp lại cho client sau một khoảng session nào đó để tránh việc token bị lộ sau thời gian quá dài.

Lợi:

Rõ ràng đây là phương thức an toàn và có độ bảo mật cao nhất để xác thực người dùng với ứng dụng và hơn thế nữa, nó cực kỳ tiết kiệm thời gian công sức. Thay vì bạn phải tự đi xây dựng một hệ thống để xác thực người dùng thì bạn có thể dựa vào các bên thứ 3 đáng tin cậy ví dụ như Facebook, Google, Twitter,...

Và thực tế thì Twitter chính là công ty đầu tiên đưa ra giải pháp bảo mật này ra thị trường. Ứng dụng chỉ cần yêu cầu người dùng đăng nhập thông qua Twitter và Twitter sẽ trả về thông tin đăng nhập cho ứng dụng, nếu Token có vấn đề hoặc có dấu hiệu bị lợi dụng thì những người phát triển ứng dụng chỉ cần vào phần quản trị của Twitter và gỡ Token đó, yêu cầu cấp Token mới là xong.

Hạn chế:

Tất nhiên là không phải hệ thống nào cũng an toàn, việc dựa dẫm vào bên thứ 3 đôi khi cũng sẽ xảy ra những ngoại lệ không mong muốn. Chắc hẳn bạn đã nghe đến phương pháp lừa đào Phishing rồi chứ? Người dùng hoàn toàn có thể bị các hacker đánh lừa và cung cấp toàn bộ thông tin cá nhân mà họ cứ tưởng là đang cung cấp cho ứng dụng của bạn.

Hơn nữa việc triển khai kỹ thuật này cũng sẽ khó khăn hơn so với 2 kỹ thuật ở trên khá nhiều nếu bạn muốn tự thiết kế một hệ thống OAuth mà không sử dụng dịch vụ của những ông lớn ở trên. Thực tế là khi đăng nhập vào Viblo, bạn cũng phải trải qua một lớp bảo mật bằng việc đăng nhập qua trang: accounts.viblo.asia - đây là một dịch vụ OAuth được Viblo xây dựng và đương nhiên là nó không đơn giản như 2 kỹ thuật kể trên

Tổng kết

Cuối cùng thì việc lựa chọn kỹ thuật nào hoàn toàn là do bạn quyết định đẻe phù hợp với ứng dụng của mình, đừng nên chỉ vì OAuth an toàn nhất mà cố sống cố chết để ép ứng dụng phải sử dụng nó, tất cả đều nằm ở yêu cầu bài toán của ứng dụng để bạn có thể rút ra một phương pháp phù hợp

Và như đã nói ở trên: Đây là những phương pháp xác thực chứ không phải một ngôn ngữ hay framework nào nên bạn có thể tự nghiên cứ để triển khai các kỹ thuật này phù hợp với ứng dụng của mình.

Cám ơn các bạn đã theo dõi bài viết! 😄


All Rights Reserved