django-pistonでAPIにBasic認証をかける

昨日django-pistonで簡単なAPIを作る方法を試してみました。
今日はそのAPIbasic認証をかけてみます。簡単です。



まず認証されるユーザーが必要です。django.contrib.auth.models.Userです。
なければpython manage.py createsuperuserで作りましょう。


続いてapi/urls.pyを修正します。
Resourceのインスタンスを作る際、キーワード引数authenticationにHttpBasicAuthenticationのインスタンスをわたします

api/urls.py

from api.handlers import TodoHandler
from django.conf.urls import patterns
from piston.authentication import HttpBasicAuthentication
from piston.resource import Resource

auth = HttpBasicAuthentication()
todo_resource = Resource(TodoHandler, authentication=auth)

urlpatterns = patterns('',
                       (r'^todo/(?P<id>\d+)/$', todo_resource),
                       (r'^todo/$', todo_resource),
                       )

これだけです。


これで認証情報なしのアクセスは401になります。

>>> r = requests.get('http://localhost:8000/api/todo/')
>>> print r
<Response [401]>


認証情報はキーワード引数authとしてわたします。

>>> r = requests.get('http://localhost:8000/api/todo/', auth=('user', 'pass'))
>>> print r
<Response [200]>

requestsを使ったひと通りのアクセス

# coding=utf-8
import requests
import json


# データを全部削除
r = requests.delete('http://localhost:8000/api/todo/', auth=('user', 'pass'))
assert(r.status_code == 204)

# データが全て消えていることを確認
r = requests.get('http://localhost:8000/api/todo/', auth=('user', 'pass'))
assert(r.status_code == 200)
assert(len(json.loads(r.text)) == 0)

# 登録
payload = {'title': u'test', 'finished': False}
r = requests.post('http://localhost:8000/api/todo/', data=json.dumps(payload), headers={"Content-Type": "application/json"}, auth=('user', 'pass'))
assert(r.status_code == 200)


#全件取得
r = requests.get('http://localhost:8000/api/todo/', auth=('user', 'pass'))
res = json.loads(r.text)
assert(r.status_code == 200)
assert(len(res) == 1)
assert(res[0]["title"] == u"test")
assert(res[0]["id"] == 1)


## idを指定して取得
r = requests.get('http://localhost:8000/api/todo/1', auth=('user', 'pass'))
res = json.loads(r.text)
assert(r.status_code == 200)
assert(res["id"] == 1)
assert(res["finished"] == False)
assert(res["title"] == u"test")

# 更新
payload = {'title': u'test', 'finished': True}
r = requests.put('http://localhost:8000/api/todo/1', data=json.dumps(payload), headers={"Content-Type": "application/json"}, auth=('user', 'pass'))
assert(r.status_code == 200)

# 更新内容を確認
r = requests.get('http://localhost:8000/api/todo/1', auth=('user', 'pass'))
res = json.loads(r.text)
assert(r.status_code == 200)
assert(res["id"] == 1)
assert(res["finished"] == True)
assert(res["title"] == u"test")


# idを指定して削除
r = requests.delete('http://localhost:8000/api/todo/1', auth=('user', 'pass'))
assert(r.status_code == 204)

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

Basic認証をかけるのはTastypieもpistonも同じくらい簡単ですね