1. 程式人生 > >基於Python下的OAuth 2.0 點點網API認證

基於Python下的OAuth 2.0 點點網API認證

一、點點API簡介

根據該網站描述,該網站採用標準的OAuth 2.0的協議,既然是標準,應該很容易移植,現在採用這種協議的網站越來越多了,開發者最多的應該是新浪了,看到新浪有Python 的SDK果斷下載下來,並進行移植。

二、SDK程式碼

oauth.py

# -*- coding: utf-8 -*-
#update by youyudehexie
#blog:http://blog.csdn.net/youyudehexie

try:
    import json
except ImportError:
    import simplejson as json
import time
import urllib
import urllib2
import logging
import webbrowser

def _obj_hook(pairs):
    '''
    
    convert json object to python object.
    '''
    o = JsonObject()
    for k, v in pairs.iteritems():
        o[str(k)] = v
    return o

class APIError(StandardError):
    '''
    raise APIError if got failed json message.
    '''
    def __init__(self, error_code, error, request):
        self.error_code = error_code
        self.error = error
        self.request = request
        StandardError.__init__(self, error)

    def __str__(self):
        return 'APIError: %s: %s, request: %s' % (self.error_code, self.error, self.request)

class JsonObject(dict):
    '''
    general json object that can bind any fields but also act as a dict.
    '''
    def __getattr__(self, attr):
        return self[attr]

    def __setattr__(self, attr, value):
        self[attr] = value

def _encode_params(**kw):
    '''
    Encode parameters.
    '''
    args = []
    for k, v in kw.iteritems():
        qv = v.encode('utf-8') if isinstance(v, unicode) else str(v)
        args.append('%s=%s' % (k, urllib.quote(qv)))
    return '&'.join(args)

def _encode_multipart(**kw):
    '''
    Build a multipart/form-data body with generated random boundary.
    '''
    boundary = '----------%s' % hex(int(time.time() * 1000))
    data = []
    for k, v in kw.iteritems():
        data.append('--%s' % boundary)
        if hasattr(v, 'read'):
            # file-like object:
            ext = ''
            filename = getattr(v, 'name', '')
            n = filename.rfind('.')
            if n != (-1):
                ext = filename[n:].lower()
            content = v.read()
            data.append('Content-Disposition: form-data; name="%s"; filename="hidden"' % k)
            data.append('Content-Length: %d' % len(content))
            data.append('Content-Type: %s\r\n' % _guess_content_type(ext))
            data.append(content)
        else:
            data.append('Content-Disposition: form-data; name="%s"\r\n' % k)
            data.append(v.encode('utf-8') if isinstance(v, unicode) else v)
    data.append('--%s--\r\n' % boundary)
    return '\r\n'.join(data), boundary

_CONTENT_TYPES = { '.png': 'image/png', '.gif': 'image/gif', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.jpe': 'image/jpeg' }

def _guess_content_type(ext):
    return _CONTENT_TYPES.get(ext, 'application/octet-stream')

_HTTP_GET = 0
_HTTP_POST = 1
_HTTP_UPLOAD = 2

def _http_get(url, authorization=None, **kw):
    print('GET %s' % url)
    return _http_call(url, _HTTP_GET, authorization, **kw)

def _http_post(url, authorization=None, **kw):
    print('POST %s' % url)
    return _http_call(url, _HTTP_POST, authorization, **kw)

def _http_upload(url, authorization=None, **kw):
    logging.info('MULTIPART POST %s' % url)
    return _http_call(url, _HTTP_UPLOAD, authorization, **kw)

def _http_call(url, method, authorization, **kw):
    '''
    send an http request and expect to return a json object if no error.
    '''
    params = None
    boundary = None
    if method==_HTTP_UPLOAD:
        params, boundary = _encode_multipart(**kw)
    else:
        params = _encode_params(**kw)
    http_url = '%s?%s' % (url, params) if method==_HTTP_GET else url 
    http_body = None if method==_HTTP_GET else params
    req = urllib2.Request(http_url, data=http_body)
    if authorization:
        req.add_header('Authorization', 'bearer %s' % authorization)
    if boundary:
        req.add_header('Content-Type', 'multipart/form-data; boundary=%s' % boundary)
        
    try:    
        resp=urllib2.urlopen(req)
    #print page.geturl()  
    #print page.info().getplist()  

    except urllib2.HTTPError, e:    
        print "Error Code:", e.code
        print 'filenam',e.filename
  
    except urllib2.URLError, e:    
        print "Error Reason:", e.reason 
    
#    resp = urllib2.urlopen(req)
    body = resp.read()
    print body
    r = json.loads(body, object_hook=_obj_hook)
    if hasattr(r, 'error_code'):
        raise APIError(r.error_code, getattr(r, 'error', ''), getattr(r, 'request', ''))
    return r

class HttpObject(object):

    def __init__(self, client, method):
        self.client = client 
        self.method = method

    def __getattr__(self, attr):
        def wrap(**kw):
            if self.client.is_expires():
                raise APIError('21327', 'expired_token', attr)
            return _http_call('%s%s.json' % (self.client.api_url, attr.replace('__', '/')), self.method, self.client.access_token, **kw)  #?????
        return wrap

class APIClient(object):
    '''
    API client using synchronized invocation.
    '''
    def __init__(self, app_key, app_secret, redirect_uri=None, response_type='code', domain='api.diandian.com', version='v1'):
        self.client_id = app_key
        self.client_secret = app_secret
        self.redirect_uri = redirect_uri
        self.response_type = response_type
        self.auth_url = 'https://%s/oauth/' % domain   
        self.api_url = 'https://%s/%s/' % (domain, version)
        self.access_token = None
        self.expires = 0.0
        self.get = HttpObject(self, _HTTP_GET)
        self.post = HttpObject(self, _HTTP_POST)
        self.upload = HttpObject(self, _HTTP_UPLOAD)

    def set_access_token(self, access_token, expires_in):
        self.access_token = str(access_token)
        self.expires = float(expires_in)

    def get_authorize_url(self, redirect_uri=None, scope='write,read'):
        '''
        return the authroize url that should be redirect.
        '''
        redirect = redirect_uri if redirect_uri else self.redirect_uri
        if not redirect:
            raise APIError('21305', 'Parameter absent: redirect_uri', 'OAuth2 request')
        return '%s%s?%s' % (self.auth_url, 'authorize', \
                _encode_params(client_id = self.client_id, \
                        response_type = 'code', \
                        scope = scope))

    def request_access_token(self, code, redirect_uri=None):
        '''
        return access token as object: {"access_token":"your-access-token","expires_in":12345678}, expires_in is standard unix-epoch-time
        '''
        redirect = redirect_uri if redirect_uri else self.redirect_uri
        if not redirect:
            raise APIError('21305', 'Parameter absent: redirect_uri', 'OAuth2 request')
        r = _http_post('%s%s' % (self.auth_url, 'token'), \
                client_id = self.client_id, \
                client_secret = self.client_secret, \
                redirect_uri = redirect, \
                code = code, grant_type = 'authorization_code')
        r.expires_in += int(time.time())
        return r
    
    def refresh_access_token(self,refresh_token):
        '''
        refresh token
        return access token as object: {"access_token":"your-access-token","expires_in":12345678}, expires_in is standard unix-epoch-time
        '''
        r = _http_get('%s%s' % (self.auth_url,'token'),\
                       client_id = self.client_id, \
                       client_secret = self.client_secret,\
                       grant_type = 'refresh_token', \
                       refresh_token = refresh_token)
        r.expires_in += int(time.time())
        return r

    def is_expires(self):
        return not self.access_token or time.time() > self.expires

    def __getattr__(self, attr):
        return getattr(self.get, attr)


三、應用例項demo

diandian.py

# -*- coding: utf-8 -*-
import oauth

if __name__=='__main__':
    CLIENT_ID = ""
    CLIENT_SECRET = ""
    CALLBACK_URL = u''
    client = oauth.APIClient(app_key=CLIENT_ID, app_secret=CLIENT_SECRET, redirect_uri=CALLBACK_URL)
    auth_url = client.get_authorize_url()
    print auth_url
    r = client.request_access_token('CODE') #返回的CODE
    client.set_access_token(r.access_token, r.expires_in)
    print client.get.user__home()  #獲取點點首頁 動態

四、待更新VERSION 1.00




相關推薦

基於PythonOAuth 2.0 點點API認證

一、點點API簡介 根據該網站描述,該網站採用標準的OAuth 2.0的協議,既然是標準,應該很容易移植,現在採用這種協議的網站越來越多了,開發者最多的應該是新浪了,看到新浪有Python 的SDK果斷下載下來,並進行移植。 二、SDK程式碼 oauth.p

WEBAPI基於Owin中介軟體實現身份驗證例項(OAUTH 2.0方式)附原始碼

1,在Webapi專案下新增如下引用: Microsoft.AspNet.WebApi.Owin Owin Microsoft.Owin.Host.SystemWeb Microsoft.Owin.Security.OAuth Microsoft.Owin.Secu

理解OAuth 2.0 - 阮一峰的絡日誌

著名 png mage parameter ali 拒絕 esp blog oot 原文:理解OAuth 2.0 - 阮一峰的網絡日誌 理解OAuth 2.0 作者: 阮一峰 日期: 2014年5月12日 OAuth是一個關

OAuth 2.0中文譯本

encode forbidden 分享服務 grant 求一個 增加 一次 access erro (一)背景知識 OAuth 2.0很可能是下一代的“用戶驗證和授權”標準,目前在國內還沒有很靠譜的技術資料。為了弘揚“開放精神&rdqu

OWIN OAuth 2.0 Authorization Server

href auth docs alt tar 參考 服務器 ges tps 參考:https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-oauth-20-authorizat

PHP OAuth 2.0 Server

ram ide ati window blob alex 申請 upgrade 客戶端 PHP OAuth 2.0 Server PHP OAuth 2.0 Server ??????????????????????????????????????????????

Postman-OAuth 2.0授權

變量 其中 發送 auth eight postman type .com acc Postman提供的授權類型有10種。授權過程將驗證是否有權從服務器訪問所需的數據。發送請求時,通常必須包含參數以確保請求有權訪問並返回所需的數據。 使用第7種OA

轉:OAuth 2.0 介紹

tgz 表示 lencod 保護 瀏覽器中 服務器申請 orm 這一 打開 OAuth是一個關於授權(authorization)的開放網絡標準,在全世界得到廣泛應用,目前的版本是2.0版。 本文對OAuth 2.0的設計思路和運行流程,做一個簡明通俗的解釋,主要參考材料

理解OAuth 2.0

發放 可選 第三方 四種 程序 ken 發送 用戶授權 解決 引用:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html OAuth是一個關於授權(authorization)的開放網絡標準,在全世界得到廣泛應用,目前的

ASP.NET WebApi OWIN 實現 OAuth 2.0(自定義獲取 Token)

href timespan 獲取 edi prot cep b- med 2-0 相關文章:ASP.NET WebApi OWIN 實現 OAuth 2.0 之前的項目實現,Token 放在請求頭的 Headers 裏面,類似於這樣: Accept: application

要用Identity Server 4 -- OAuth 2.0 超級簡介

分隔 理解 大小 很多 應用程序 identity 復制 字符串 返回 OAuth 2.0 簡介 OAuth有一些定義: OAuth 2.0是一個委托協議, 它可以讓那些控制資源的人允許某個應用以代表他們來訪問他們控制的資源, 註意是代表這些人, 而不是假冒或模仿這些人

(轉阮一峰)深入理解OAuth 2.0

MF refresh 告訴 agent example 運行流程 可見 緩存 但是 OAuth是一個關於授權(authorization)的開放網絡標準,在全世界得到廣泛應用,目前的版本是2.0版。 本文對OAuth 2.0的設計思路和運行流程,做一個簡明通俗的解釋,主要參

OAuth 2.0之授權碼模式

sse 解釋 wiki value 選擇 可見 blank rect www. 轉載自:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html OAuth 2.0授權碼模式 授權碼模式(authorization code

Web驗證方式--OAuth 2.0協議(1)

store all 微信 cache 裏的 spa 瀏覽器 圖像 cal 介紹 OAuth協議是用來解決第三方應用程序訪問Http Service的時候的認證問題。舉個例子:某視頻網站支持用戶通過微信登陸,然後獲取用戶在微信上的圖像信息。 在這個場景裏   微信充當的

Python 購物車練習 2.0

iphone6 iphone 當前 product art cycle while 商品 enume product_list = [ [‘iphone6s‘, 5800], [‘mac book‘, 9000], [‘coffee‘, 32], [

OracleLinux6.5Oracle11.2.0.4的安裝

following 升級 打開終端 alt min oinstall 路徑 product 設置環境變量 接http://blog.51cto.com/12784425/2310379此文1、準備工作Oracle11.2.0.4的安裝包;VNC客戶端vnc Viewer;

Win10OpenCV3.2.0+VS2015配置

注:       1)本文參考毛星雲的部落格配置過程,裡面有很多詳細的講解,有興趣可以移步;       2)配置完畢後的程式碼測試,可以參考 這裡。       &nb

《阿里巴巴MongoDB4.0高階實戰:基於Java Spring Boot 2.0》運維、監控、聚合、叢集、監控等高階面試題

《阿里巴巴MongoDB4.0高階實戰》阿里巴巴技術大牛 資深專家P9葉翔、專家徐雷.  NoSQL排名第一!最流行的NoSQL資料庫;谷歌、阿里巴巴、螞蟻金服、騰訊、百度等一線網際網路公司必備技能。 本系列課程涵蓋:MongoDB入門命令、管理、聚合分析、核心架構、資料庫管理、匯入匯出、索引、

OAuth 2.0 筆記 (6) Bearer Token 的使用方法

文章目錄 場景 原文地址 摘選片段 場景 最近在研究oauth2認證, 剛好這篇文章很優秀, MARK一下 原文地址 原文地址 https://blog.yo

IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架學習保護API

IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架學習之保護API。 使用IdentityServer4 來實現使用客戶端憑據保護ASP.NET Core Web API 訪問。 IdentityServer4 GitHub: https://g