เท่าที่ดู code น่าจะติด 3 อันนี้หล่ะ
1 ต้องเป็น app
2 user ต้องกดอนุญาติ ตย เช่น เวลาเราเพิ่ม app บน fb เราต้องกดตกลง
3 ต้อง implement oauth เพื่อให้ได้ access_token มา
จุดหลักในการทำ fb app มี 2ข้อยากๆ
1 oauth เป็นระบบ login dialog ของ fb ที่จะแสดงให้ผู้ใช้งานกดตกลง
2 การรับข้อมูลหลังการ login
การ implement oauth ถ้าไม่ใช้ Facebook php sdk พูดได้เลยว่า เสียเวลาหมาๆ เอ๊ย มากๆ ยาก+เยอะ
คุ้นๆว่า ถ้าเป็ฯ app + web login ไม่ต้อง oauth ก็ได้ แค่ยิง app_id ไป ที่หน้า social login แล้ว fb จะยิงกลับมาเอง
ส่วนในเคสนี้ ขั้นตอนการทำจนได้ accesstoken อธิบายคร่าวๆตามนี้
1 ไปสมัครเป็น app
2 ไปตั้ง app setting ให้มัน redirect มาหน้าเวปเรา(หน้าเวป หรือหน้า app canvas)
3 เมื่อต้องการให้ user login ก็ redirect user ไป login dialog ของ fb
4 จากนั้น fb จะยิง req ด้วยการ post กลับมาที่เวปเรา
5 query string มี 2 ส่วน คือ signed_request กับ encoded_sig
6 ถอดรหัสตามด้านล่าง
7 นำ app secret ที่ได้ตอนลงทะเบียน fb app มาเพื่อถอดรหัส encoded_sig (รหัสที่ได้มาพร้อม app id)
8 ถ้า encoded sig แล้วตรงกัน data ที่มันโพสมาอีกตัว แสดงว่า ข้อมูลที่ได้ ถูกต้อง
9 ใน json ที่ได้ จะมี field ชื่อ access_token ก็เอาอันนั้นแหละ มายิง req
แถม code ถอดรหัส fb request เป็น python + django เอาของในเน็ตมาแล้ว เขียนแก้เองใหม่
เวลาใช้ก็
def test(self): return "f0i1KiAELqTuJtJ31jf62JkRZEGq3W35Lg.eyJhbG0aG0iOiJITU ยาวมากๆ"
fb = facebook(self.test())
fb.data คือข้อมูล user ในรูป json แต่ใน python เป็น dict ทั่วไปก็มี uid, access_token
** สังเกตุว่า ตัว string ที่ fb มันโพสมา จะมีจุด คั่นกลาง ถ้า split แล้ว
- ครึ่งแรก จะเรียกว่า payload เอามาถอด base64 ตามด้วยถอด hmac ด้วย app secret จะได้ string ค่านึง เพื่อตรวจสอบความถูกต้อง
- ครึ่งหลัง เป็น base64 encode ธรรมดา เมื่อถอดออก จะได้ json และถ้าเอาข้อมูลก่อนถอด ไปเข้ารหัส hmac จะต้องตรงกับ payload
ลองอ่านจาก code ละกันคับ อธิบายเอง งงเอง
class facebook(object):
def app_secret(self): return "c2103xxxxxac9861a"
def __init__(self, signed_request):
self.data = self.parse_signed_request(signed_request)
def decode_signed_request(self, inp):
padding_factor = (4 - len(inp) % 4) % 4
inp += "="*padding_factor
return base64.b64decode(unicode(inp).translate(dict(zip(map(ord, u'-_'), u'+/'))))
def parse_signed_request(self, signed_request):
l= signed_request.split('.', 2)
encoded_sig = l[0]
payload = l[1]
sig = self.decode_signed_request(encoded_sig)
data = simplejson.loads(self.decode_signed_request(payload))
if data.get('algorithm').upper() != 'HMAC-SHA256':
log.error('Unknown algorithm')
return None
else:
expected_sig = hmac.new(self.app_secret(), msg=payload, digestmod=hashlib.sha256).digest()
if sig != expected_sig:
return None
else:
log.debug('valid signed request received..')
return data
ขอเม้าขำๆ แก้เบื่อ ที่มาของ app python ที่ผมเขียน (เป็น fb app ตัวที่สาม) คือ
ช่วงหลังๆ เห็นมีคนนิยมขายของกันใน fb เยอะ และทุกคนบ่นเหมือนกันหมด ว่า จะทำไงให้ shop สวย
ผมเลยเกิดไอเดียว่า น่าจะทำเป็น app tab ที่ ผู้ขาย สามารถเข้าไปเพิ่มลด สินค้า แก้ไขข้อมูลได้ง่าย และเปลี่ยน themeได้เอง ส่วนผู้ซื้อ ก็แค่เปิด fb page ขึ้นมาก็จบ
ประเด็นคือ ไม่อยากลงทุน เลยหา host free แต่ fb บังคับว่า app ต้องเป็น https จนในที่สุด มาเจอ google app engine ที่ให้บริการฟรี ประเด็นคือมันบังคับให้ 3 ภาษา คือ java + jsp, python, GO
java นั้น เยอะเกินไป คือcode เยอะเกิน ไม่เหมาะกับ app นี้ ตั้งใจว่า อยากทำเป็น code หลังบ้านไม่เยอะ เน้นเป็ฯ json ที่เหลือเป็น javascript จะทำง่ายกว่า เร็วกว่า สวยกว่า มานั่งใช้ jsp
ส่วนภาษา GO ก็ไม่น่าเสี่ยง เพราะพึ่งเกิดใหม่ และมีแต่ google ที่ใช้ เลยไม่รู้จะเขียนไปทำไม
สุดท้าย เลยมาลงที่ python พอได้อ่าน พบว่ามันง่ายมาาาก โครงสสร้างภาษาเป็น mvc แต่กำเนิด syntac อ่านง่ายมากๆ มี แถม lamda function แค่นี้ก็ดีกว่า java มากโขแล้ว
เริ่มเขียนขำๆได้ วันสองวัน พอเอาขึ้น server แม่มดันมี error กับ python 2.7 ตอนนี้เลยกะว่า หลังปีใหม่ค่อยมา port ลง 2.5 และทำต่อ