Sử dụng tham số signed_request để kiểm tra like app

Rất nhiều bạn hỏi làm sao để kiểm tra xem người dùng (user) đã like page hay app hay chưa, hoặc bắt buộc phải like page thì mới sử dụng được app. Việc này sẽ giúp bạn bảo vệ nội dung (content) hay muốn tăng lượng thành viên trên fanpage của bạn một cách hiệu quả.

images Tham số signed_request được facebook sử dụng để gửi dữ liệu đến app theo một vài cách khác nhau kèm theo thông tin về user_id và một vài thông tin cơ bản khác về người dùng (user) ví dụ như tuổi, địa phương, đất nước. Những thông tin này rất có ích trong việc hạn chế theo một vài yêu cầu nếu có trong app.

Bài này sẽ mô tả chi tiết các bước chuẩn bị cần thiết:

Yêu cầu cơ bản:

Trước tiên bạn cần phải có một facebook app đã thiết lập đầy đủ các thông tin sau để có thể nhận được tham số signed_request:

-Canvas Apps: signed_request được gửi cho app khi app được nạp trong Canvas page.
-Page Apps: signed_request được gửi cho app khi app được nạp trong Page apps
-Thiết lập Apps with Deauthorized Callback URL: signed_request sẽ được gửi đến Deauthorized Callback URL (trong phần Dashboard Settings) khi user xóa bỏ quyền truy cập của app đối với user đó trong phần thiết lập tài khoản của user.
-Apps sử dụng Registration Plugin: signed_request được gửi đến app nếu app sử dụng Registration plugin khi user đăng ký thành công một plugin nào đó.
-Apps sử dụng Javascript SDK để đăng nhập: khi sử dụng đăng nhập bằng Javascript SDK thì đối tượng authResponse sẽ chứa thuộc tính signed_request.

Code mẫu:

Đọc xong bài viết này bạn sẽ có một hàm cơ bản để sử dụng trong app của mình để lấy, xử lý và xác nhận tham số signed_request trong 2 bước.

Bước 1: Lọc tham số signed_request

Như đã đề cập bên trên tham số signed_request có rất nhiều cách khác nhau để gửi đến app. Có thể thông qua phương thức request/response hoặc thông qua đối tượng JSON. Nhưng nói chung cả 2 cách ta đều có thể lấy được tham số signed_request mong muốn. Dưới đây chúng ta xử lý dựa trên PHP:

if ($_REQUEST) {
  $signed_request = $_REQUEST['signed_request'];
} else {
  echo '$_REQUEST is empty';
}

và sử dụng Javascript SDK:

FB.getLoginStatus(function(response) {
  if (response.status === 'connected') {
    var signedRequest = response.authResponse.signedRequest;
  }
 });

Việc lọc signed_request sẽ sinh ra một đối tượng JSON chứa một vài dữ liệu. Nội dung và cấu trúc của nó được tạo ra phụ thuộc cách ta yêu cầu nhưng nói chung vẫn có thể lấy ra cái mà ta cần giống nhau trong bài này. Sau đây là cách xử lý bằng PHP:

function parse_signed_request($signed_request) {
  list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

  // decode the data
  $sig = base64_url_decode($encoded_sig);
  $data = json_decode(base64_url_decode($payload), true);

  return $data;
}

function base64_url_decode($input) {
  return base64_decode(strtr($input, '-_', '+/'));
}

Code bên trên sẽ sinh ra một đối tượng JSON có cấu trúc gần giống sau đây:

{
   "oauth_token": "...chuỗi khá dài...",
   "algorithm": "HMAC-SHA256",
   "expires": 1291840400,
   "issued_at": 1291836800,
   "registration": {
      "name": "Xman Prince",
      "email": "xman@user.vn",
      "location": {
         "name": "Hà Nội, Việt Nam",
         "id": 110931812264243
      },
      "gender": "male",
      "birthday": "10/03/1988",
      "like": true,
      "phone": "983572627",
      "anniversary": "",
      "captain": "",
      "force": "",
      "live": {
         "name": "Hà Nội, Việt Nam",
         "id": 110931812264243
      }
   },
   "registration_metadata": {
      "fields": "[\n {'name':'name'},\n {'name':'email'},\n {'name':'location'},\n {'name':'gender'},\n {'name':'birthday'},\n {'name':'password'},\n {'name':'like',       'description':'Do you like this plugin?', 'type':'checkbox',  'default':'checked'},\n {'name':'phone',      'description':'Phone Number',             'type':'text'},\n {'name':'anniversary','description':'Anniversary',              'type':'date'},\n {'name':'captain',    'description':'Best Captain',             'type':'select',    'options':{'P':'','K':''}},\n {'name':'',      'description':'Which side?',              'type':'select',    'options':{'jedi':'Jedi','sith':'Sith'}, 'default':'sith'},\n {'name':'live',       'description':'Best Place to Live',       'type':'typeahead', 'categories':['city','country','state_province']},\n {'name':'captcha'}\n]"
   },
   "user_id": "1253953317"
}

Bước 2: Xác nhận tham số signed_request

Khi bạn nhận được tham số signed_request bạn có thể kiểm tra nó với chuỗi App secret để chắn chắn rằng chuỗi này được gửi bởi facebook chứ không phải bên nào khác. Bây giờ tiến hành sửa hàm bên trên một chút:

function parse_signed_request($signed_request, $secret) {
  list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

  // decode the data
  $sig = base64_url_decode($encoded_sig);
  $data = json_decode(base64_url_decode($payload), true);

  if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
    error_log('Unknown algorithm. Expected HMAC-SHA256');
    return null;
  }

  // Adding the verification of the signed_request below
  $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
  if ($sig !== $expected_sig) {
    error_log('Bad Signed JSON signature!');
    return null;
  }

  return $data;
}

Chúng ta đã thêm một phần code vào việc kiểm tra hàm tạo lại signed_request từ nội dung dự kiến sẽ nhận được và so sánh nó với nội dung chúng ta thật sự nhận được.

Chữ ký HMAC giúp cho bạn có thể kiểm tra thực sự xem việc yêu cầu được trả về từ facebook. Một phần của chữ ký được tạo từ tham số App secret của bạn mà chỉ bạn và facebook mới biết code secret này. Nếu không có code secret này cũng đồng nghĩa với việc bên thứ 3 không thể can thiệp vào được và cũng tương đương với nội dung sẽ không hợp lệ.

Did you like this? Share it:

Tham khảo:

  • http://cachvaofacebook.com cách vào facebook

    cảm ơn đã chia sẻ, nhưng mình ko biết cách khi cho người ta like 1 site khác thì mới được chơi app chứng ko phải là like app

  • Kentucky

    bạn ơi hiện tại có nhiều app,khi click để chơi thì hiện ra bảng danh sách bạn bè (đã check mời tất cả bạn bè ) có biết code đó không ????có thể chỉ mình không ????

    • http://thegioimanguon.com xman

      bạn chờ bài viết sau nhé, nhất định mình sẽ viết, đợt trước tạo nhiều app quá bị facebook block xóa hết app và kô cho tạo app nữa :(