การป้องกันการ hack In-app Purchase (2) by heha
Oct1
ต่อจากบทความที่แล้ว วันนี้เรามาดูขั้นตอนการ verify จริงๆ กัน มีดังนี้
Android
- Login เข้า https://play.google.com/apps/publish/
- เลือก Settings (Icon ฟันเฟือง)
- เลือก API Access แล้วกดเปิดใช้งาน Google Play Android Developer API
- ที่หัวข้อ Linked Project ใน API Access หลังเปิดใช้งานให้คลิกที่ Google Play Android Developer
- คลิก APIs & auth
- คลิก Credentials
- คลิกปุ่ม Create new Client ID
- เลือก Application Type เป็น Web Application
- ช่อง Authorized Javascript Origins และ Authorized Redirect URI ใส่เป็น http://google.com หรืออะไรก็ได้ทั้งคู่ แต่ให้จำค่าในช่องนี้ไว้
- จด Client ID กับ Client Secret เอาไว้
- กด Create Client ID
- ใส่ช่อง 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) - คลิก Allow Access
- Browser จะ redirect ไป google.com (หรือเว็บอื่นตาม redirect_uri ที่ตั้งไว้) แต่เราไม่ต้องสนใจตัวเนื้อหาในเว็บ ให้ดูที่ URL ที่มัน redirect ไปสังเกตดูจะพบตัวแปร code ใน url ของ browser หน้าตาประมาณนี้ “
4/eWdxD7b-YSQ5CNNb-c2iI83KQx19.wp6198ti5Zc7dJ3UXOl0T3aRLxQmbwI
.” (เป็นแค่ข้อมูลตัวอย่าง ต้องใช้ของคุณเอง) ก็ให้ copy ข้อมูลส่วนนี้เก็บเอาไว้ - ลง Google Chrome Extension Postman (หรือ extension อื่นๆ เอาไว้ให้ทดสอบยิง GET/POST ผ่าน web browser ได้ง่ายๆ)
- เปิด Postman แล้วเลือกประเภทการยิง request เป็น POST
- เลือกประเภทเป็น 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>
-
- กด Send จะได้รับข้อมูลมาเป็น JSON ให้ Copy ส่วนของ refresh_token เก็บไว้ใช้งานตลอดไปใน server ของเราเองเลย (refresh_token ไม่มีวันหมดอายุ ไม่ต้องขอใหม่ ใช้ได้ตลอด)
- (ตั้งแต่ข้อนี้เป็นต้นไปให้คุณทดลองใช้ 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>
-
- copy ข้อมูลส่วนของ access_token เก็บไว้
- ใช้ 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
-
- ได้ผลลัพธ์มาหน้าตาแบบนี้
{ "kind": "androidpublisher#productPurchase", // ค่าคงที่มาแบบนี้เสมอทุกครั้ง "purchaseTimeMillis": long, // เวลาที่สั่งซื้อ เป็น milliseconds "purchaseState": integer, // สถานะการสั่งซื้อ 0 เป็นซื้อสำเร็จ และ 1 คือยกเลิกการสั่งซื้อ "consumptionState": integer, // สถานะการใช้งาน 0 คือรอการใช้งานและ 1 คือใช้งานไปแล้ว "developerPayload": string // ค่าที่เราส่งมาจากฝั่ง client ที่จะเก็บใน server ของ google ไว้ด้วย เช่น transaction id ของเราที่สร้างขึ้นมาเอง }
- เรียบร้อยจ้า
iOS
- ข้อมูลจาก client (มือถือผู้ใช้) จะมาในรูปแบบ payload ซึ่งเป็น string json ยาวๆ ก้อนหนึ่งถูก encode ด้วย base64 เอาไว้ ให้ยิงข้อมูลจาก client (มือถือผู้ใช้) มายัง server
- ที่ฝั่ง 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 อาจเป็นข้อมูลการสั่งซื้อครั้งแรก ไม่ใช่ข้อมูลการสั่งซื้อปัจจุบัน)
- เสร็จแล้วจ้า
ข้อมูลอ้างอิง:
https://developers.google.com/android-publisher/api-ref/purchases/products/get
https://developers.google.com/android-publisher/authorization
Enjoy this article?
Consider subscribing to our RSS feed!
16:02 on September 30th, 2015
ขอบคุณมากครับบบบ