4
我想用Django實現一個具有過濾資源訪問(OAuth認證)的Web服務,我有幾個問題。OAuth Web服務和Django活塞
我創建了兩個Web服務器:
- http://localhost:8080:網絡服務提供商(使用Django活塞爲WebService)
- http://localhost:8000:Web服務消費者
我想使用的版本1.0a的OAuth來驗證消費者對提供商。該協議的工作流程描述如下:here。
概括地說,這裏有不同的步驟(資源的名稱交換):
- 的消費者從提供商請求令牌(密鑰,密鑰)
- 如果消費者有效,提供商返回一個令牌(oauth_token,oauth_token_secret)
- 消費者將用戶重定向到該提供商登錄/准許訪問(組oauth_token)
- 的用戶許可獲得了消費者的資源。
- 的提供商給消費者令牌驗證(token_verifier)
- 的消費者請求一個的access_token(鑰匙,祕密,組oauth_token,oauth_token_secret,oauth_verifier)
- 的提供商給消費者 access_token(oauth_token)
- 消費者使用其oauth_token訪問資源
這裏是我的消費者的意見代碼:
from django.shortcuts import render_to_response
from django.http import HttpResponse, HttpResponseRedirect
import oauth2 as oauth
import urlparse
REQUEST_TOKEN_URL = 'http://127.0.0.1:8080/api/authentication/request_token/'
AUTHORIZATION_URL = 'http://127.0.0.1:8080/api/authentication/authorize/'
ACCESS_TOKEN_URL = 'http://127.0.0.1:8080/api/authentication/access_token/'
CONSUMER_CALLBACK_URL = 'http://127.0.0.1:8000/request_access_token/'
CONSUMER_KEY = 'key'
CONSUMER_SECRET = 'secret'
consumer = oauth.Consumer(CONSUMER_KEY, CONSUMER_SECRET)
client = oauth.Client(consumer)
def request_token(request):
"""
Contacts the service provider to get a token.
"""
resp, content = client.request(REQUEST_TOKEN_URL, 'GET')
oauth_token = dict(urlparse.parse_qsl(content)).get('oauth_token', None)
oauth_token_secret = dict(urlparse.parse_qsl(content)).get('oauth_token_secret',
None)
if oauth_token is None:
return render_to_response('home.html', {'data': 'NO TOKEN FOUND'})
else:
request.session['oauth_token'] = oauth_token
request.session['oauth_token_secret'] = oauth_token_secret
return HttpResponseRedirect('request_user_permission/')
def request_user_permission(request):
"""
Redirects the user to the service provider to get permission if
token provided.
"""
oauth_token = request.session['oauth_token']
if oauth_token is None:
return render_to_response('home.html', {'data': 'NO TOKEN FOUND'})
else:
return HttpResponseRedirect("%s?oauth_token=%s&oauth_callback=%s"
% (AUTHORIZATION_URL, oauth_token, CONSUMER_CALLBACK_URL))
def request_access_token(request):
"""
Requests an access token from the service provider
if the user granted permission.
"""
error = request.GET.get('error', None)
if error is None:
oauth_verifier = request.GET.get('oauth_verifier', None)
if oauth_verifier is None:
return render_to_response('home.html',
{'data': 'UNKNOWN ERROR HAPPENED'})
else:
# User permission granted, requesting access token
oauth_token = request.session['oauth_token']
oauth_token_secret = request.session['oauth_token_secret']
token = oauth.Token(oauth_token, oauth_token_secret)
token.set_verifier(oauth_verifier)
client.token = token
resp, content = client.request(ACCESS_TOKEN_URL, 'POST')
access_token = dict(urlparse.parse_qsl(content))
return render_to_response('home.html', {'data': access_token})
else:
return render_to_response('home.html', {'data': error})
一般OAuth的問題
- 消費者應該有多少令牌呢?一?每個用戶一個?每個資源一個?
- 消費者應該如何存儲其令牌?
- 如何指定消費者可以使用其令牌訪問哪些資源?消費者不應該在將用戶重定向到服務提供商時提供想要訪問的資源的ID(步驟3)?
- 如果消費者想要訪問用戶已經爲其授予訪問權限的資源,是否應該將用戶重定向到服務提供者(並讓服務提供者立即返回oauth_verifier,而不是詢問用戶許可)?
技術問題
現在,我使用本地內存中緩存的會話存儲令牌,但它不工作:
- 當會話對消費者激活服務器,用戶必須每次都在服務提供商服務器上登錄(即使他已經登錄)。
- 在第一個視圖(請求令牌)中,我將
oauth_token
和oauth_token_secret
存儲在請求的會話中。當我嘗試在第二個視圖中訪問它時(在重定向用戶之前),它可以工作。但是,當我嘗試訪問它在最後一個視圖(重定向後)不(KeyError
,oauth_token
沒有在request.session
字典中找到)
謝謝!