django-tastypieのOAuthAuthenticationを試す

依存ライブラリをインストールします

pip install python-provider
pip install oauth2


Resourceクラスでauthentication = OAuthAuthentication()を記述します

from tastypie.authentication import OAuthAuthentication
from tastypie.resources import ModelResource
from tastypie.authorization import Authorization
from app.models import Book


class BookResource(ModelResource):
    class Meta:
        queryset = Book.objects.all()

        #authentication = BasicAuthentication()
        #authentication = ApiKeyAuthentication()
        #authentication = DigestAuthentication()
        authentication = OAuthAuthentication()

        authorization = Authorization()


必要なモデルを作成するため、INSTALLED_APPSにoauth_providerを追加します

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'app',
    'tastypie',
    'oauth_provider',
)


syncdbでoauth_providerで定義されているモデルのテーブルが作成されます

Creating tables ...
Creating table oauth_provider_nonce
Creating table oauth_provider_resource
Creating table oauth_provider_consumer
Creating table oauth_provider_token
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)


consumerを作成

>>> from oauth_provider.models import Consumer, Token
>>> c = Consumer()
>>> c.generate_random_codes()
>>> c
Out[9]: <Consumer: Consumer  with key 0c5e29c244a749249efbaace2ebfec4c>
>>> c.key
Out[10]: '0c5e29c244a749249efbaace2ebfec4c'
>>> c.secret
Out[11]: 'KHfAEapMBP3HDFke'


access_tokenを作成

>>> from django.contrib.auth.models import User
>>> u = User.objects.all()[0]
>>> t = Token()
>>> t.user = u
>>> t.consumer = c
>>> t.token_type = 2
>>> t.generate_random_codes()
>>> t.key
Out[27]: 'c4dda9d6537444769b4a49b0dbb4a63c'
>>> t.secret
Out[28]: 'JZQpB75KshdXPEqq'

アクセスするクライアント側ではrequestsのoauth用のプラグインを使います

pip install requests-oauth

requests-oauthを使ったアクセスの例

# coding=utf-8
import json
import requests
from oauth_hook import OAuthHook

consumer_key = '0c5e29c244a749249efbaace2ebfec4c'
consumer_secret = 'KHfAEapMBP3HDFke'
access_token = 'c4dda9d6537444769b4a49b0dbb4a63c'
access_token_secret = 'JZQpB75KshdXPEqq'

oauth_hook = OAuthHook(access_token=access_token,
                       access_token_secret=access_token_secret,
                       consumer_key=consumer_key,
                       consumer_secret=consumer_secret,
                       header_auth=True)

client = requests.session(hooks={'pre_request': oauth_hook})

# データを全部削除
r = client.delete('http://localhost:8000/api/book/')
assert(r.status_code == 204)

# データが全て消えていることを確認
r = client.get('http://localhost:8000/api/book/')
assert(json.loads(r.text)["meta"]["total_count"] == 0)

## 登録
payload = {'title': u'Python Cook Book', 'pub_date': "2012/9/25"}
r = client.post('http://localhost:8000/api/book/',
                data=json.dumps(payload),
                headers={"Content-Type": "application/json"})
assert(r.status_code == 201)

### 取得
r = client.get('http://localhost:8000/api/book/')
res = json.loads(r.text)
assert(len(res["objects"]) == 1)
assert(res["objects"][0]["title"] == u"Python Cook Book")
assert(int(res["objects"][0]["id"]) == 1)

# idを指定して取得
r = client.get('http://localhost:8000/api/book/1/')
res = json.loads(r.text)
assert(int(res["id"]) == 1)
assert(res["title"] == u"Python Cook Book")

# 更新
payload = {'id': 1,
           'title': u'Python Cook Book 2nd Edition',
           'pub_date': "2013/1/25"}
r = client.post('http://localhost:8000/api/book/',
                data=json.dumps(payload),
                headers={"Content-Type": "application/json"})
assert(r.status_code == 201)


# 更新内容を確認
r = client.get('http://localhost:8000/api/book/1/')
res = json.loads(r.text)
assert(int(res["id"]) == 1)
assert(res["title"] == u"Python Cook Book 2nd Edition")


# idを指定して削除
r = client.delete('http://localhost:8000/api/book/1/')
assert(r.status_code == 204)

# データが消えていることを確認
r = client.get('http://localhost:8000/api/book/1/')
assert(r.status_code == 404)