การป้องกันการ hack In-app Purchase (2) by

31
Oct
1

ต่อจากบทความที่แล้ว วันนี้เรามาดูขั้นตอนการ verify จริงๆ กัน มีดังนี้

Android

  1. Login เข้า https://play.google.com/apps/publish/
  2. เลือก Settings (Icon ฟันเฟือง)
  3. เลือก API Access แล้วกดเปิดใช้งาน Google Play Android Developer API
  4. ที่หัวข้อ Linked Project ใน API Access หลังเปิดใช้งานให้คลิกที่ Google Play Android Developer
  5. คลิก APIs & auth
  6. คลิก Credentials
  7. คลิกปุ่ม Create new Client ID
  8. เลือก Application Type เป็น Web Application
  9. ช่อง Authorized Javascript Origins และ Authorized Redirect URI ใส่เป็น http://google.com หรืออะไรก็ได้ทั้งคู่ แต่ให้จำค่าในช่องนี้ไว้
  10. จด Client ID กับ Client Secret เอาไว้
  11. กด Create Client ID
  12. ใส่ช่อง url ใน Web Browser ไปว่า
    https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=...&client_id=...
    (แก้ใข … เป็นข้อมูลจากข้อ 9-10)
  13. คลิก Allow Access
  14. Browser จะ redirect ไป google.com (หรือเว็บอื่นตาม redirect_uri ที่ตั้งไว้) แต่เราไม่ต้องสนใจตัวเนื้อหาในเว็บ ให้ดูที่ URL ที่มัน redirect ไปสังเกตดูจะพบตัวแปร code ใน url ของ browser หน้าตาประมาณนี้ “4/eWdxD7b-YSQ5CNNb-c2iI83KQx19.wp6198ti5Zc7dJ3UXOl0T3aRLxQmbwI.” (เป็นแค่ข้อมูลตัวอย่าง ต้องใช้ของคุณเอง) ก็ให้ copy ข้อมูลส่วนนี้เก็บเอาไว้
  15. ลง Google Chrome Extension Postman (หรือ extension อื่นๆ เอาไว้ให้ทดสอบยิง GET/POST ผ่าน web browser ได้ง่ายๆ)
  16. เปิด Postman แล้วเลือกประเภทการยิง request เป็น POST
  17. เลือกประเภทเป็น form-data แล้วกรอก URL ไปว่า
    https://accounts.google.com/o/oauth2/token
    โดยกรอกข้อมูลในช่อง key, value ข้างใต้ดังนี้ (key:value)

    • grant_type : authorization_code
    • code : <ข้อมูลจากข้อ 14>
    • client_id : <ข้อมูลจากข้อ 10>
    • client_secret : <ข้อมูลจากข้อ 10>
    • redirect_uri : <ข้อมูลจากข้อ 9>
  18. กด Send จะได้รับข้อมูลมาเป็น JSON ให้ Copy ส่วนของ refresh_token เก็บไว้ใช้งานตลอดไปใน server ของเราเองเลย (refresh_token ไม่มีวันหมดอายุ ไม่ต้องขอใหม่ ใช้ได้ตลอด)
  19. (ตั้งแต่ข้อนี้เป็นต้นไปให้คุณทดลองใช้ postman ยิงไปดูก่อน หลังจากทำจนเสร็จแล้วเห็นว่าใช้งานได้ ให้ทำใหม่ตั้งแต่ข้อนี้เป็น code ฝั่ง server ของคุณเองโดยอาจยิง Curl ไปเพื่อให้กระบวนการขอ access_token เป็นไปโดยอัตโนมัติไม่ต้องใช้งานผ่าน browser เพื่อตรวจสอบความถูกต้องของการสั่งซื้อกับ Server Google) ใช้ postman เลือกยิงแบบ POST เหมือนเดิมไปที่ url
    https://accounts.google.com/o/oauth2/token
    โดยกรอก key:value ดังนี้

    • grant_type : refresh_token
    • client_id : <ข้อมูลจากข้อ 10>
    • client_secret : <ข้อมูลจากข้อ 10>
    • refresh_token: <ข้อมูลจากข้อ 18>
  20. copy ข้อมูลส่วนของ access_token เก็บไว้
  21. ใช้ postman เลือกยิง url แบบ GET ไปที่
    https://www.googleapis.com/androidpublisher/v2/applications/<packageName>/purchases/products/<product_id>/tokens/<token>?access_token=<access_token>

    • packageName - ชื่อ package ของ app เช่น com.lvup.pokdeng
    • product_id - product_id ที่สร้างจากบทความที่แล้ว
    • token - purchase token ที่ได้จาก app ฝั่ง client (มื่อถือผู้ใช้)หลังซื้อสำเร็จที่เราสั่งให้ยิงมาที่ server ของเราเพื่อตรวจสอบ (คิดซะว่าเป็น transaction id ที่ทาง google สร้างขึ้น)
    • access_token – ข้อมูลจากข้อ 20
  22. ได้ผลลัพธ์มาหน้าตาแบบนี้
    {
      "kind": "androidpublisher#productPurchase", // ค่าคงที่มาแบบนี้เสมอทุกครั้ง
      "purchaseTimeMillis": long, // เวลาที่สั่งซื้อ เป็น milliseconds
      "purchaseState": integer, // สถานะการสั่งซื้อ 0 เป็นซื้อสำเร็จ และ 1 คือยกเลิกการสั่งซื้อ
      "consumptionState": integer, // สถานะการใช้งาน 0 คือรอการใช้งานและ 1 คือใช้งานไปแล้ว
      "developerPayload": string // ค่าที่เราส่งมาจากฝั่ง client ที่จะเก็บใน server ของ google ไว้ด้วย เช่น transaction id ของเราที่สร้างขึ้นมาเอง
    }
  23. เรียบร้อยจ้า

iOS

  1. ข้อมูลจาก client (มือถือผู้ใช้) จะมาในรูปแบบ payload ซึ่งเป็น string json ยาวๆ ก้อนหนึ่งถูก encode ด้วย base64 เอาไว้ ให้ยิงข้อมูลจาก client (มือถือผู้ใช้) มายัง server
  2. ที่ฝั่ง server ให้เรายิงแบบ POST ไปที่ url

    https://sandbox.itunes.apple.com/verifyReceipt

    (สำหรับ transaction ที่ใช้ทดสอบ) หรือ

    https://buy.itunes.apple.com/verifyReceipt

    สำหรับ server จริง ซึ่งถ้าใช้ postman ในการทดสอบยิงจะต้องเปลี่ยนชนิดที่เลือกจาก form-data เป็น raw แล้วเอาข้อมูล json string ทั้งก้อนที่ได้รับมา มาเปลี่ยนจาก “receipt_base64″ เป็น “receipt-data” แล้วยิงเข้า  url ที่กล่าวไว้ จะได้รับข้อมูลมาเป็น JSON ถ้า status เป็น 0 แสดงว่ายิงสำเร็จ จะมีข้อมูลอื่นๆ ติดมาด้วยโดยให้เช็คจาก array ชื่อ in_app เป็นหลัก และดูที่สมาชิก array ตัวสุดท้าย จะเป็นรายการล่าสุดที่พึ่งสั่งซื้อจริงๆ (หาก array มีข้อมูลมากกว่า 1 บางครั้งจะมีข้อมูลการสั่งซื้อครั้งก่อนๆ ให้มาด้วย จึงต้องตรวจสอบจากสมาชิกตัวสุดท้ายของ array เสมอ) โดยมีข้อมูลที่น่าเก็บไว้คือ product_id, transaction_id และ purchase_date_ms (หากมีคำว่า original อาจเป็นข้อมูลการสั่งซื้อครั้งแรก ไม่ใช่ข้อมูลการสั่งซื้อปัจจุบัน)

  3. เสร็จแล้วจ้า

ข้อมูลอ้างอิง:

https://developers.google.com/android-publisher/api-ref/purchases/products/get

https://developers.google.com/android-publisher/authorization

https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html

Enjoy this article?

Consider subscribing to our RSS feed!

1 ความเห็น

  1. PichIsHandsome
    16:02 on September 30th, 2015

    ขอบคุณมากครับบบบ

ใส่ความเห็น

RSS feed for comments on this post