人人開放平臺客戶端OAuth認證及API的使用[python]

新博客地址:http://gorthon.sinaapp.com/

注:本文爲了敘述方便,沒有將UI與邏輯分離。本文只是介紹方法,至於代碼的可讀性,還請原諒。

1. 獲取API Key和SECRET,在創建應用的時候會告訴你這兩個值。

以下是一些全局變量:

APIKEY = '11111111111111111' # 這裏假設用1表示獲得的api key
SECRET = '2222222222222222' # 這裏假設用2表示獲得的secret


ACCESS_TOKEN = ''

# 獲取Authorization Code 的URI
AUTHORIZATION_URI = 'https://graph.renren.com/oauth/authorize'

# 獲取Access Token 的URI
ACCESS_TOKEN_URI = 'https://graph.renren.com/oauth/token'

# 人人API Server URI,以後通過POST的方式獲取數據,都從這個URI獲得
API_SERVER = 'http://api.renren.com/restserver.do'

得到access token之後現在不用session key了。查看詳情


2. 引導用戶授權

url = '%s?client_id=%s&redirect_uri=http://graph.renren.com/oauth/login_success.html&response_type=token&display=popup' % (AUTHORIZATION_URI, APIKEY)

print url

將打印出來的url輸入瀏覽器就會進入授權頁面

這裏我用了PyQt4所以直接在客戶端裏面嵌入了一個QWebView

def oauth(self):
        url = QUrl('%s?client_id=%s&redirect_uri=http://graph.renren.com/oauth/login_success.html&\
response_type=token&display=popup' % (AUTHORIZATION_URI, APIKEY))
        self.web_view.load(url)

這樣就可以直接在客戶端嵌入的瀏覽器裏面進行用戶授權。這裏由於要攔截授權後的一個url(因爲這個url裏面包含了access token),要響應QWebView的urlChanged信號,

所以事先在__init__中設置self.web_view.urlChanged.connect(self.urlChanged)

然後:

def urlChanged(self, url):
        url = unicode(url.toString())
        if url.find('access_token') > 0:
            global ACCESS_TOKEN
            try:
                ACCESS_TOKEN = re.findall(r'access_token=(.*)&', url)[0]
                QMessageBox(
                    QMessageBox.Information,
                    u'授權成功',
                    u'您已成功爲此程序授權!',
                    ).exec_()
            except IndexError:
                ACCESS_TOKEN = ''
            file('./conf.txt', 'w').write('access_token:%s' % ACCESS_TOKEN)

這裏我只是簡單的將access token保存在了一個txt文件中。

這樣之後,基本上就算是完成一半了,以後都要代上這個ACCESS_TOKEN進行POST。

3. sig的計算以及POST

爲了安全起見,需要將POST的參數進行簽名認證。

計算sig的方法,這裏借用官方的demo:

    def _getParams(self, params):
        params['sig'] = self._getSig(params)
        return params
    
    def _getSig(self, params):
        return hashlib.md5(''.join(['%s=%s' % (x, params[x]) 
                for x in sorted(params.keys())]) + SECRET).hexdigest()

這兩個也可以組合成一個函數來用。其中_getSig爲計算要POST的參數的字典,此時字典裏面不包含sig(因爲還沒有計算出來……),然後返回計算好的sig(一個md5值)。這樣以後在要POST的時候將要POST的字典進行下面類似操作即可:

params = {'uid':'10086', 'name':'shuji'}

params = _getParams(params)

post(url, params)

像上面這樣的僞代碼就可以了。

這裏我進行了簡單地“封裝”,就不用像上面這樣寫這麼多代碼:

def post(self, params):
        '''
        返回一個json格式的字典
        '''
        result = json.loads(self.net.post(API_SERVER, self._getParams(params)))
        if isinstance(result, list):
            return result[0]
        return result

以後要POST的時候只需:

params = {'uid':'10086', 'name':'shuji'}

self.post(params)

就可以了。注意:這裏默認的POST的url是API_SERVER。

其中有個self.net.post這個是我另外寫的一個專門用來POST的類,因爲這個代碼可以我經常用,我就直接拉過來還用了。

代碼如下(netbase.py)

# _*_ encoding:utf-8 _*_
import urllib2
import urllib
import cookielib

class Net(object):
    def __init__(self):
        self.cookie = cookielib.LWPCookieJar()
        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie))
        self.opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1;\
zh-CN; rv:1.9.2.3) #Gecko/20100401 Firefox/3.6.3')]
        urllib2.install_opener(self.opener)

    def post(self, url, params):
        return self.opener.open(urllib2.Request(url, urllib.urlencode(params))).read()

    def get(self, url):
        return self.opener.open(urllib2.Request(url)).read()


4. 使用舉例

比如我們要獲取某個用戶最近來訪好友的列表:

def getVisitors(self):#獲得某個用戶最近來訪的列表
        info = ''
        visitors = self.post({'access_token':ACCESS_TOKEN,
            'method':'users.getVisitors', 'v':'1.0', 'format':'JSON'})[u'visitors']
        for visitor in visitors:
            #print visitor[u'name'], visitor[u'time'], visitor[u'uid'], visitor[u'headurl']
            info += '%s, %s, %s, %s\n' % (visitor[u'name'], visitor[u'time'], visitor[u'uid'], visitor[u'headurl'])
        self.label.setText(u'最近訪問好友列表:\n%s' % info)

可以用一個QLabel來顯示最近訪問好友的列表,當然如果你要顯示頭像也是可以的,如下:

        head = QPixmap()
        head.loadFromData(self.net.get(vistor[u'headurl']))
        self.label_head.setPixmap(head)

其餘的到官網的API文檔裏面看就是了,猛擊這裏

代碼就不上傳了,寫得很爛。

應網友要求,放到Github上面了,以後不要在這裏求代碼了哈。https://github.com/Shu-Ji/xiaonei_oauth


最後來幾張爛圖:







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章