[Hỏi trao đổi kiến thức] Flow lấy access token của Tini App

Chào anh chị

Em đọc documents hướng dẫn lấy access token thấy khá phức tạp ạ, e biết mình đang làm theo luồng Authorization Code của OAuth 2.0.

E có một thắc mắc nhỏ là thay vì trả lại auth code thì sao ko trả lại access token luôn các anh nhỉ ?

https://developers.tiki.vn/docs/api/open/get-auth-code

Thanks mọi người đã đọc ạ.

Hi QuyNV, cái này theo như mình hiểu thì AuthCode là duy nhất đối với 1 user, nhưng user đó đối với mỗi App thì lại cho phép App các quyền truy cập khác nhau, vậy nên phải dùng access token để quản lý việc đó. vì vậy AuthCode và AccessToken có mục đích sử dụng khác nhau.

Vì 2 bước này khá tách biệt, và có các kịch bản sử dụng kết hợp với nhiều luồng khác nữa chứ ko chỉ kết hợp với nhau như bạn thấy ở đây. ngoài ra mỗi hàm có các lỗi khác nhau, ko liên quan về ý nghĩa nên gộp lại với nhau chỉ làm rối kiến trúc của hệ thống.

3 Likes

Hi @QuyNV
Việc trả về auth_code thay vì access_token sẽ giúp các bạn thiết kế được một luồng authentication cho Tini App của bạn bảo mật hơn.

1/ Vì sao trả về access token là không tốt
Thực tế thì cơ chế trả về access token như này rất phổ biến (các công ty như Google, Facebook) để sử dụng cơ chế này để trả về cho users.
Tuy nhiên, cơ chế này gây ra lỗi bảo mật cho rất nhiều ứng dụng.

Để giải thích rõ hơn, chúng ta hãy cùng xem xét các kịch bản tấn công khi trả về access_token.
Trong trường hợp này, để tích hợp luồng auth, mỗi một Tini App sẽ cần làm các công việc sau

Với luồng làm việc như này, các bạn developers khi xây dựng backend cho một Tini App, sẽ cần expose ra một API login với tiki access token.
API được sử dụng ở bước số 4 như trên hình.
API này nhận vào tiki access token của một tiki user.
Một trong những lỗi bảo mật thường thấy của API này đó là: các developers không kiểm tra xem access token này có phải là access token được tiki cấp cho Tini App của họ hay không.

Ví dụ

  • Frontend của App A nhận được tiki access token
  • Sau đó, Frontend của App A gửi access token này tới Backend của App B
  • Nếu như Backend của App B không kiểm tra access token xem token này có phải là thuộc về app App B, thì App A có thể lấy được users của App B

Lỗi này cực kỳ nguy hiểm, vì nó cho phép một ứng dụng bất kỳ có thể lấy toàn bộ uses của một ứng dụng khác.

Tưởng tượng rằng, bạn login vào AirBnb bằng tài khoản facebook của bạn. Bạn gắn credit card vào AirBnB để thanh toán tiền trên đó.
Sau đó, bạn chơi một mini game nho nhỏ trên Facebook. Và mini game đó có thể lấy được thông tin về thẻ tín dụng của bạn trên AirBnb.
Điều này thực sự khá là điên rồ

Để rõ hơn, về cơ chế tấn công trên Facebook, bạn có thể đọc thêm bài viết này

Giải pháp của những công ty như Google và Facebook, để giảm thiểu lỗi cho developers đó là viết document và bảo developers chú ý kiểm tra lỗi
Tuy nhiên, vẫn còn rất nhiều ứng dụng (kể cả những ứng dụng thuộc các công ty lớn vẫn mắc lỗi này).

Nói tóm lại, trả về access_token, thì việc bảo mật ứng dụng đòi hỏi developers phải làm nhiều việc hơn, cẩn thận hơn

2/ Vì sao trả về auth code lại tốt hơn
Với auth_code, luồng làm việc gần như tương tư

Điểm khác biệt so với luồng ở trên là có thể bước exchange auth code lấy token.
Chú ý rằng bước exchange auth code này chỉ thực hiện ở backend, và để lấy được token này, developers phải truyền vào

  • app_id
  • app signature được sinh ra từ app secret

Khi Tini App Backend của developers gửi authCode, cũng như appId lên backend của Tiki. Backend của Tiki có thể biết được authCode này có được cấp cho appId hay không.
Và nếu như authCode không thuộc về appId, Tiki sẽ trả về lỗi ngay lập tức

Bằng cơ chế này, kịch bản tấn công như trình bày ở phần 1 sẽ không thể thực hiện được. Và ứng dụng của developers sẽ tránh được lỗi bị mất account.

Tuy nhiên, để thực hiện được cơ chế này, developers vẫn cần phải đảm bảo một điều: bạn bắt buộc phải implement cơ chế exchage auth code lấy token ở backend

Một điều quan trọng nữa, đừng bao giờ lộ ra appId và appSecret của bạn cho bất kỳ ai khác.

Mình hy vọng câu trả lời này giải đáp được thắc mắc của bạn.

4 Likes

Thanks anh Kiên vì câu trả lời rất chi tiết ạ :))

E hỏi thêm chút ạ: Trong luồng trả lại ngay Access Token cho Mini App Frontend: Nếu Tini App Backend thực hiện verify Access Token và có thực hiện kiểm tra xem Access Token này có phải dành cho mini app của mình không (so sánh claim aud của Access Token chẳng hạn) thì mức độ bảo mật của 2 flow trên là như nhau phải ko ạ ? Hay còn lỗ hổng nào khác ko a ?

Đúng rồi @QuyNV nhé. Nếu backend thực hiện việc kiểm tra này thì mức độ bảo mật của 2 luồng như nhau. Về usability thì luồng lấy token trực tiếp sẽ tiện hơn, nhưng mà nó cũng dễ cho developer xử lý sai hơn. Luồng OAuth2 thông thường với sự tham gia của backend để exchange token có thể nói là “fool-proof” vì developer rất khó làm sai flow trong luồng này.

1 Like

Thanks các anh đã hỗ trợ rất nhiệt tình ạ :slightly_smiling_face:

1 Like