views:

582

answers:

1

Hi, i'm trying to build a facebook API client using python, code follows:

import os
import urllib2
import urllib
import cookielib
import hashlib
import json

USER = ''
PASS = ''
LOGIN = 'http://www.facebook.com/login.php?login_attempt=1'
HOST = 'http://api.facebook.com/restserver.php'
API_KEY = 'eca5c767f0e5b65942419574374c34a4'
SECRET_KEY = 'e2aab4000e08f4199f3ca6793ab4f02c'

def getSig(params, secret):
  sigStr = ''
  for k in sorted(params.keys()):
    sigStr += k + '=' + params[k]
  sigStr += secret
  return hashlib.md5(sigStr).hexdigest()

def call(host, params):
  basicParams = {'api_key': API_KEY,
                 'format': 'JSON',
                 'v': '1.0'}
  basicParams.update(params)
  basicParams['sig'] = getSig(basicParams, SECRET_KEY)
  finalParams = urllib.urlencode(basicParams)

  cj = cookielib.LWPCookieJar()

  opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj), urllib2.HTTPRedirectHandler)
  urllib2.install_opener(opener)

  request = urllib2.Request(host)

  request.add_header('User-Agent', 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100402 Ubuntu/9.10 (karmic) Firefox/3.5.9')
  request.add_header('Content-Type', 'application/x-www-form-urlencoded')

  h = urllib2.urlopen(request, finalParams)

  return h.read()


def getToken():
  paramsRaw = {'method': 'Auth.createToken',
               'api_key': API_KEY,
  }
  ret = call(HOST, paramsRaw)

  return json.loads(ret)

def login(user, password, token):
  # post login form
  paramsRaw = {
               'auth_token': token,
               'email': user,
               'pass': password,
  }
  call(LOGIN, paramsRaw)

def getSession(token):
  paramsRaw = {'method': 'Auth.getSession',
               'auth_token': token
              }
  print call(HOST, paramsRaw)

def main():
  token = getToken()
  login(USER, PASS, token)
  getSession(token)

main()

I'm basically receiving a token from Auth.createToken, POSTing it with USER/PASS to facebook.com/login.php and sending the same token to Auth.getSession (as outlined here: http://wiki.developers.facebook.com/index.php/Auth.createToken) But getSession returns error 100 ("Invalid parameter"), what am i doing wrong? Are there any examples of similar programs on the web?

A: 

You also need a call_id parameter which can be based on time.time(), as well as a method parameter.

rlotun
You mean while POSTing to login.php? What method parameter should I pass then? The documentation for Auth.getSession/Auth.createToken explicitly says that they do not need a call_id (http://wiki.developers.facebook.com/index.php/Auth.createToken, http://wiki.developers.facebook.com/index.php/Auth.getSession)
Julius
Just noticed that you don't use FB connect. Are you implementing a desktop app? You still need to redirect the user to a webpage to log in (http://wiki.developers.facebook.com/index.php/Authorization_and_Authentication_for_Desktop_Applications). Otherwise you should use Facebook Connect (http://wiki.developers.facebook.com/index.php/Authorization_and_Authentication_for_Desktop_Applications). Programmatically logging the user is not a good thing. You can do it once and save tokens if you want for later - but you have to do a web login at least once.
rlotun
Yes, that's the point of the question - programmatically logging the user in, and getting the session key for the API. It's supposed to be a server-side handler and i want to have control over the logging process (no browser launching or direct user-browser interaction). So - why is it a bad idea and how can i do it?
Julius
Well, will it be a different user each time? If so, it's a bad idea because Facebook specifically mandates they want users to log in via the web process. If it's a single user, or a set of known users what you can do is perform a one time Facebook connect for those users, and save the key and secret you get from that. Then you can perform actions for users as you require. You may also find this stackoverflow question helpful: http://stackoverflow.com/questions/798785/login-into-facebook-with-php-script-but-let-me-logged-in-the-browser-after-the-e
rlotun