Tạo quy trình đăng nhập theo cách thủ công

Đối với quy trình đăng nhập dựa trên trình duyệt cho một ứng dụng web hoặc ứng dụng dành cho máy tính mà không sử dụng các SDK - chẳng hạn như ở chế độ xem web của ứng dụng gốc dành cho máy tính (ví dụ: Windows 8) hoặc quy trình đăng nhập sử dụng toàn bộ mã phía máy chủ, bạn có thể tự mình tạo Quy trình đăng nhập bằng cách sử dụng các lệnh chuyển hướng trình duyệt. Thông qua hướng dẫn này, bạn sẽ hiểu rõ từng bước của quy trình đăng nhập và cách triển khai mỗi bước đó mà không cần sử dụng SDK của chúng tôi:

Để sử dụng phương thức Đăng nhập bằng Facebook trên ứng dụng dành cho máy tính, bạn có thể phải nhúng một trình duyệt web (đôi khi gọi là chế độ xem web) trong ứng dụng để thực hiện quy trình đăng nhập.

Kiểm tra trạng thái đăng nhập

Các ứng dụng dùng SDK của chúng tôi có thể kiểm tra xem ai đã đăng nhập bằng chức năng tích hợp. Tất cả các ứng dụng khác phải tạo cách lưu trữ riêng khi có người đăng nhập. Khi không có chỉ báo đó, ứng dụng phải tiếp tục với giả định rằng họ đã đăng xuất. Nếu ai đó đăng xuất thì ứng dụng của bạn phải chuyển hướng họ đến hộp thoại Đăng nhập vào thời điểm thích hợp, ví dụ như khi họ nhấp vào nút đăng nhập.

Đăng nhập mọi người

Dù ai đó chưa đăng nhập vào ứng dụng của bạn hoặc chưa đăng nhập vào Facebook, bạn có thể sử dụng hộp thoại Đăng nhập để nhắc họ thực hiện cả hai việc đó. Nếu chưa đăng nhập vào Facebook, người đó sẽ được nhắc đăng nhập vào ứng dụng này rồi tiếp tục đăng nhập vào ứng dụng của bạn. Hoạt động này được phát hiện tự động. Vì vậy, bạn không cần hành động gì thêm để kích hoạt hành vi này.


Gọi hộp thoại Đăng nhập và đặt URL chuyển hướng

Ứng dụng của bạn phải bắt đầu lệnh chuyển hướng đến một điểm cuối sẽ hiển thị hộp thoại đăng nhập:

https://www.facebook.com/v19.0/dialog/oauth?
  client_id={app-id}
  &redirect_uri={redirect-uri}
  &state={state-param}

Điểm cuối này có các thông số bắt buộc sau:

  • client_id. ID ứng dụng có trong bảng điều khiển ứng dụng của bạn.
  • redirect_uri. URL mà bạn muốn chuyển hướng người dùng khi đăng nhập trở lại. URL này sẽ ghi lại phản hồi từ hộp thoại Đăng nhập. Nếu đang dùng URL này ở chế độ xem web trong ứng dụng dành cho máy tính, bạn phải đặt URL này thành https://www.facebook.com/connect/login_success.html. Bạn có thể xác nhận rằng URL này được đặt cho ứng dụng của bạn trong Bảng điều khiển ứng dụng. Bên dưới phần Sản phẩm trong menu điều hướng bên trái của Bảng điều khiển ứng dụng, hãy nhấp vào Đăng nhập bằng Facebook rồi nhấp vào Cài đặt. Xác minh URI chuyển hướng OAuth hợp lệ trong phần Cài đặt OAuth ứng dụng.
  • state. Một giá trị dạng chuỗi do ứng dụng của bạn tạo để duy trì trạng thái giữa yêu cầu và lệnh gọi lại. Thông số này sẽ được dùng để ngăn chặn các cuộc tấn công Giả mạo yêu cầu trên nhiều trang web và sẽ được chuyển lại cho bạn nguyên vẹn trong URI chuyển hướng của bạn.

Ví dụ: nếu yêu cầu đăng nhập của bạn có dạng như sau:

https://www.facebook.com/v19.0/dialog/oauth?
  client_id={app-id}
  &redirect_uri={"https://www.domain.com/login"}
  &state={"{st=state123abc,ds=123456789}"}

thì URI chuyển hướng của bạn sẽ được gọi bằng mã sau:

https://www.domain.com/login?state="{st=state123abc,ds=123456789}"
    

Mã này cũng có các thông số không bắt buộc sau:

  • response_type. Xác định xem dữ liệu phản hồi có nằm trong các thông số hoặc phân đoạn URL khi diễn ra hoạt động chuyển hướng trở lại ứng dụng hay không. Hãy xem phần Xác nhận danh tính để chọn loại danh tính mà ứng dụng của bạn sẽ dùng. Có thể là một trong số các lựa chọn sau:
    • code. Dữ liệu phản hồi được đưa vào dưới dạng thông số URL và chứa thông số code (một chuỗi được mã hóa dành riêng cho từng yêu cầu đăng nhập). Đây là hành vi mặc định nếu thông số này không được chỉ định. Dữ liệu này hữu ích nhất khi máy chủ của bạn sử dụng mã.
    • token. Dữ liệu phản hồi được đưa vào dưới dạng phân đoạn URL và chứa mã truy cập. Ứng dụng dành cho máy tính phải sử dụng cài đặt này cho response_type. Dữ liệu này hữu ích nhất khi ứng dụng xử lý mã.
    • code%20token. Dữ liệu phản hồi được đưa vào dưới dạng phân đoạn URL và chứa cả mã truy cập lẫn thông số code.
    • granted_scopes. Trả về danh sách được phân tách bằng dấu phẩy gồm tất cả các Quyền mà người dùng cấp cho ứng dụng tại thời điểm đăng nhập. Có thể được kết hợp với các giá trị response_type khác. Khi kết hợp với token, dữ liệu phản hồi được đưa vào dưới dạng phân đoạn URL, nếu không sẽ ở dạng thông số URL.
  • scope. Một danh sách được phân tách bằng dấu phẩy hoặc dấu cách gồm các Quyền để yêu cầu từ người dùng ứng dụng của bạn.
Đối với các ứng dụng Windows 8

Nếu định tạo Quy trình đăng nhập cho ứng dụng Windows, bạn có thể dùng Thông tin nhận dạng bảo mật gói làm redirect_uri của mình. Kích hoạt Hộp thoại Đăng nhập bằng cách gọi WebAuthenticationBroker.AuthenticateAsync và dùng điểm cuối Hộp thoại Đăng nhập làm requestUri. Dưới đây là một ví dụ trong JavaScript:

var requestUri = new Windows.Foundation.Uri(
  "https://www.facebook.com/v19.0/dialog/oauth?
    client_id={app-id}
    &display=popup
    &response_type=token
    &redirect_uri=ms-app://{package-security-identifier}");

Windows.Security.Authentication.Web.WebAuthenticationBroker.authenticateAsync(
  options,
  requestUri)
  .done(function (result) {
    // Handle the response from the Login Dialog
  }
);

Yêu cầu này sẽ trả lại quy trình kiểm soát cho ứng dụng của bạn kèm theo mã truy cập khi thành công hoặc lỗi khi thất bại.

Xử lý phản hồi của hộp thoại Đăng nhập

Tại thời điểm này của quy trình đăng nhập, người dùng sẽ nhìn thấy hộp thoại Đăng nhập và có thể chọn hủy hoặc cho phép ứng dụng truy cập vào dữ liệu của họ.

Nếu chọn OK trên hộp thoại Đăng nhập, người dùng ứng dụng sẽ cấp quyền truy cập vào trang cá nhân công khai, danh sách bạn bè của họ và mọi Quyền khác mà ứng dụng của bạn đã yêu cầu.

Trong mọi trường hợp, trình duyệt sẽ chuyển về ứng dụng và hệ thống sẽ có thêm dữ liệu phản hồi cho biết liệu ai đó đã kết nối hay hủy. Khi ứng dụng của bạn dùng phương thức gián tiếp như ở trên, redirect_uri mà ứng dụng trả về sẽ được thêm vào thông số hoặc phân đoạn URL (theo response_type đã chọn). Bạn phải ghi lại thông tin này.

Do ứng dụng web có thể dùng những tổ hợp ngôn ngữ mã khác nhau, nên hướng dẫn của chúng tôi không nêu ví dụ cụ thể. Tuy nhiên, các ngôn ngữ hiện đại nhất sẽ có khả năng phân tích cú pháp URL như sau:

JavaScript phía máy khách có thể ghi lại các phân đoạn URL (ví dụ: jQuery BBQ), trong khi đó các thông số URL có thể được ghi lại bằng cả mã phía máy khách lẫn mã phía máy chủ (ví dụ: $_GET trong PHP, jQuery.deparam trong jQuery BBQ, querystring.parse trong Node.js hoặc urlparse trong Python). Microsoft cung cấp hướng dẫn và mã mẫu cho các ứng dụng Windows 8 kết nối với một "nhà cung cấp online" - trong trường hợp này là Facebook.

Khi dùng một ứng dụng dành cho máy tính và đăng nhập, Facebook sẽ chuyển hướng người dùng đến redirect_uri được đề cập ở trên và đặt mã truy cập cùng với một số siêu dữ liệu khác (chẳng hạn như thời gian hết hạn của mã) trong phân đoạn URI:

https://www.facebook.com/connect/login_success.html#
    access_token=ACCESS_TOKEN...

Ứng dụng của bạn cần phát hiện hoạt động chuyển hướng này, sau đó đọc mã truy cập ngoài URI bằng cơ chế do hệ điều hành cung cấp và khung phát triển mà bạn đang sử dụng. Khi đó, bạn có thể chuyển thẳng sang bước Kiểm tra mã truy cập.


Đăng nhập bị hủy

Nếu không chấp nhận hộp thoại Đăng nhập và nhấp vào Hủy, người dùng ứng dụng sẽ được chuyển hướng đến:

YOUR_REDIRECT_URI?
 error_reason=user_denied
 &error=access_denied
 &error_description=Permissions+error.

Hãy xem phần Xử lý quyền bị thiếu để biết thêm về những hoạt động mà ứng dụng sẽ thực hiện khi người dùng từ chối đăng nhập.

Xác nhận danh tính

Quy trình chuyển hướng này liên quan đến những trình duyệt được chuyển hướng đến các URl trong ứng dụng của bạn từ hộp thoại Đăng nhập. Vì vậy, lưu lượng truy cập có thể truy cập trực tiếp vào URL này bằng các phân đoạn hoặc thông số có sẵn. Nếu ứng dụng giả định rằng đây là những thông số hợp lệ, dữ liệu có sẵn sẽ được ứng dụng của bạn sử dụng cho các mục đích có khả năng gây hại. Do đó, ứng dụng của bạn phải xác nhận rằng người dùng ứng dụng cũng chính là người có trong dữ liệu phản hồi trước khi bạn tạo mã truy cập cho họ. Việc xác nhận danh tính được thực hiện theo những cách khác nhau tùy thuộc vào response_type nhận được ở trên:

  • Khi nhận được code, mã này phải được đổi lấy mã truy cập bằng cách sử dụng một điểm cuối. Lệnh gọi này cần phải diễn ra giữa các máy chủ vì có liên quan đến khóa bí mật của ứng dụng. (Khóa bí mật của ứng dụng không được kết thúc bằng mã ứng dụng.)
  • Khi nhận được token, mã này cần phải được xác minh. Bạn cần thực hiện lệnh gọi API đến một điểm cuối kiểm tra. Điểm cuối này sẽ cho biết đối tượng nhận mã và ứng dụng tạo mã. Lệnh gọi API này yêu cầu sử dụng mã truy cập ứng dụng, do đó, đừng bao giờ thực hiện lệnh gọi này từ một máy khách. Thay vào đó, hãy thực hiện lệnh gọi này từ một máy chủ mà bạn có thể lưu trữ an toàn khóa bí mật của ứng dụng.
  • Khi nhận được cả codetoken, bạn nên thực hiện cả hai bước.

Lưu ý rằng bạn cũng có thể tạo thông số state riêng và dùng thông số đó với yêu cầu đăng nhập của mình để cung cấp khả năng bảo vệ CSRF.

Đổi mã lấy mã truy cập

Để lấy mã truy cập, hãy gửi yêu cầu HTTP GET đến điểm cuối OAuth sau:

GET https://graph.facebook.com/v19.0/oauth/access_token?
   client_id={app-id}
   &redirect_uri={redirect-uri}
   &client_secret={app-secret}
   &code={code-parameter}

Điểm cuối này có một số thông số bắt buộc sau:

  • client_id. ID của ứng dụng
  • redirect_uri. Đối số này là bắt buộc và phải giống với request_uri gốc mà bạn sử dụng khi bắt đầu quy trình đăng nhập OAuth.
  • client_secret. Khóa bí mật duy nhất của ứng dụng, có trên Bảng điều khiển ứng dụng. Tuyệt đối không đưa khóa bí mật của ứng dụng này vào mã phía máy khách hoặc mã nhị phân có thể giải mã. Cần phải giữ bí mật tuyệt đối vì khóa bí mật của ứng dụng là yếu tố cốt lõi trong việc bảo mật ứng dụng của bạn và tất cả người dùng.
  • code. Thông số nhận được từ lệnh chuyển hướng hộp thoại Đăng nhập ở trên.

Lưu ý: Từ phiên bản 2.3 trở đi, điểm cuối này sẽ trả về một phản hồi JSON thích hợp. Nếu lệnh gọi của bạn không chỉ định phiên bản thì phiên bản mặc định sẽ là phiên bản có sẵn cũ nhất.

Phản hồi

Phản hồi bạn nhận được từ điểm cuối này sẽ được trả về ở định dạng JSON và nếu thành công là:

{
  "access_token": {access-token}, 
  "token_type": {type},
  "expires_in":  {seconds-til-expiration}
}

Nếu không thành công, bạn sẽ nhận được thông báo lỗi giải thích.

Kiểm tra mã truy cập

Dù có sử dụng code hoặc token làm response_type từ hộp thoại Đăng nhập hay không, ứng dụng của bạn đều sẽ nhận được mã truy cập. Bạn có thể thực hiện các hoạt động kiểm tra tự động đối với những mã này thông qua một điểm cuối API Đồ thị:

GET graph.facebook.com/debug_token?
     input_token={token-to-inspect}
     &access_token={app-token-or-admin-token}

Điểm cuối này lấy những thông số sau:

  • input_token. Mã bạn cần kiểm tra.
  • access_token Một mã truy cập ứng dụng hoặc mã truy cập cho nhà phát triển của ứng dụng.

Phản hồi của lệnh gọi API là một mảng JSON chứa dữ liệu về mã được kiểm tra. Ví dụ:

{
    "data": {
        "app_id": 138483919580948, 
        "type": "USER",
        "application": "Social Cafe", 
        "expires_at": 1352419328, 
        "is_valid": true, 
        "issued_at": 1347235328, 
        "metadata": {
            "sso": "iphone-safari"
        }, 
        "scopes": [
            "email", 
            "publish_actions"
        ], 
        "user_id": "1207059"
    }
}

Trường app_iduser_id giúp ứng dụng của bạn xác minh rằng mã truy cập là hợp lệ cho người đó và cho ứng dụng của bạn. Để xem mô tả đầy đủ về các trường khác, hãy tham khảo Hướng dẫn cách xem thông tin về mã truy cập.

Kiểm tra quyền

Cạnh /me/permissions có thể được gọi để truy xuất danh sách các quyền mà một người dùng cụ thể đã cấp hoặc từ chối. Ứng dụng của bạn có thể dùng cạnh này để kiểm tra xem ứng dụng không thể dùng những quyền được yêu cầu nào cho một người dùng cụ thể.

Yêu cầu lại quyền bị từ chối

Với phương thức Đăng nhập bằng Facebook, mọi người có thể từ chối chia sẻ một số quyền với ứng dụng của bạn. Hộp thoại Đăng nhập có một màn hình như sau:

Quyền public_profile luôn được yêu cầu và có màu xám vì bạn không thể vô hiệu hóa quyền này.

Tuy nhiên, nếu ai đó định bỏ chọn user_likes (Lượt thích) trong ví dụ này, việc kiểm tra /me/permissions về quyền đã được cấp sẽ dẫn đến:

{
  "data":
    [
      {
        "permission":"public_profile",
        "status":"granted"
      },
      {
        "permission":"user_likes",
        "status":"declined"
      }
    ]
}

Lưu ý rằng người này đã từ chối cấp quyền user_likes.

Bạn có thể yêu cầu một người cấp lại cho ứng dụng của bạn những quyền mà họ đã từ chối. Bạn phải hiển thị một màn hình cho biết lý do bạn nghĩ họ nên cấp quyền đó cho bạn rồi yêu cầu lại. Tuy nhiên, nếu bạn gọi hộp thoại Đăng nhập như trước đây, hộp thoại Đăng nhập sẽ không yêu cầu quyền đó.

Đó là vì sau khi ai đó từ chối một quyền, hộp thoại Đăng nhập sẽ không yêu cầu lại quyền đó trừ khi bạn nói rõ lý do bạn yêu cầu lại quyền bị từ chối.

Để thực hiện hành động này, hãy thêm thông số auth_type=rerequest vào URL hộp thoại Đăng nhập của bạn:

https://www.facebook.com/v19.0/dialog/oauth?
    client_id={app-id}
    &redirect_uri={redirect-uri}
    &auth_type=rerequest
    scope=email
   

Khi bạn thực hiện việc này, hộp thoại Đăng nhập sẽ yêu cầu lại quyền bị từ chối.

Lưu trữ mã truy cập và trạng thái đăng nhập

Tại thời điểm này của quy trình, đã có ai đó xác thực và đăng nhập. Ứng dụng đã sẵn sàng thực hiện lệnh gọi API thay mặt họ. Trước khi thực hiện, ứng dụng sẽ lưu trữ mã truy cập và trạng thái đăng nhập của người dùng ứng dụng.

Lưu trữ mã truy cập

Sau khi ứng dụng nhận được mã truy cập từ bước trước, mã này phải được lưu trữ để khả dụng với tất cả các phần của ứng dụng khi ứng dụng đó thực hiện lệnh gọi API. Không có quy trình cụ thể nhưng nhìn chung, nếu tạo một ứng dụng web, bạn nên thêm mã làm biến của phiên để xác định phiên của trình duyệt đó với một người cụ thể. Nếu tạo một ứng dụng gốc dành cho máy tính hoặc thiết bị di động, bạn nên sử dụng kho lưu trữ dành cho ứng dụng của mình. Ngoài ra, ứng dụng nên lưu trữ mã trong cơ sở dữ liệu cùng với user_id để xác định mã.

Vui lòng xem ghi chú của chúng tôi về kích thước mã truy cập trong tài liệu về mã truy cập.

Theo dõi trạng thái truy cập

Ứng dụng của bạn nên lưu trữ trạng thái đăng nhập của người dùng. Điều này giúp tránh phải thực hiện các lệnh gọi bổ sung đến hộp thoại Đăng nhập. Dù chọn quy trình nào, hãy sửa đổi hoạt động kiểm tra trạng thái đăng nhập để giải thích.

Đăng xuất mọi người

Bạn có thể đăng xuất mọi người khỏi ứng dụng bằng cách hoàn tác bất kể chỉ báo trạng thái đăng nhập nào bạn đã thêm, ví dụ: xóa phiên cho biết một người đã đăng nhập. Bạn cũng nên xóa mã truy cập đã lưu trữ.

Việc đăng xuất người dùng không giống với thu hồi quyền đăng nhập (gỡ phương thức xác thực đã cấp trước đó), có thể được thực hiện riêng biệt. Vì lý do này, hãy tạo ứng dụng sao cho ứng dụng không tự động buộc những người đã đăng xuất quay lại hộp thoại Đăng nhập.

Phát hiện khi mọi người gỡ cài đặt ứng dụng

Mọi người có thể gỡ cài đặt ứng dụng qua Facebook.com mà không cần tương tác với chính ứng dụng. Để hỗ trợ các ứng dụng phát hiện khi điều này xảy ra, chúng tôi cho phép các ứng dụng cung cấp URL gọi lại bỏ ủy quyền. URL này sẽ được gọi mỗi khi trường hợp này xảy ra.

Bạn có thể kích hoạt lệnh gọi lại bỏ ủy quyền qua Bảng điều khiển ứng dụng.

Phản hồi yêu cầu xóa dữ liệu của người dùng

Mọi người có thể yêu cầu một ứng dụng xóa tất cả thông tin về họ mà ứng dụng đó nhận được từ Facebook. Để phản hồi những yêu cầu này, hãy xem phần Lệnh gọi lại yêu cầu xóa dữ liệu.