2013-10-09 40 views
0

我想用非ORM數據源使用Django,並且在通過我的自定義後端訪問其他資源而未經任何驗證成功時,現在我需要引入用戶驗證。沒有本地數據庫。當我收到一個請求時(例如,使用用戶名和密碼創建的cURL命令),我需要對遠程URL執行HTTP基本認證,並且在成功時,我應該返回一個本地創建的用戶對象,它只有一個用戶名,沒有什麼奇特的。所以在我的Tastypie資源,我寫了這樣的事情:通過TastyPie驗證非ORM用戶資源

class dict2obj(object): 
    """ 
    Convert dictionary to object 
    @source http://stackoverflow.com/a/1305561/383912 
    """ 
    def __init__(self, d): 
     self.__dict__['d'] = d 

    def __getattr__(self, key): 
     value = self.__dict__['d'][key] 
     if type(value) == type({}): 
      return dict2obj(value) 
     return value 


class RemoteAuth(Authentication): 
    def is_authenticated(self, request, **kwargs): 
     username = request.user.username 
     password = request.user.password 
     r = requests.get(AUTHENTICATION_URL, auth=(username, password)) 
     if r.status_code == 200: 
      return True 
     return False 



class UserResource(Resource):    
    username = fields.CharField(attribute='username') 

    class Meta: 
     resource_name = 'user' 
     authentication = RemoteAuth() 
     authorization = Authorization() 

     def obj_get_list(self, request=None, **kwargs): 

      result = [] 

      posts.append(dict2obj(
      { 
      'username': request.POST.get('username'), 
      } 
      )) 

      return result 

但是,當然,這是不行的,因爲認證對象無法獲取密碼這樣的。請建議一種處理刪除用戶身份驗證而不涉及任何本地數據庫的好方法。

+0

成功請求登錄端點後,您是否曾嘗試將'username'和'password'存儲在'session'中?您可以通過SSL提供登錄API,使其更安全一些。 –

+0

我不知道該怎麼做。你能指點我一些示例代碼嗎?我的印象是Tastypie資源是一個端點。我試圖訪問'http:// localost:8000/api/v1/user /?format = json' –

+0

我將提交它作爲一個單獨的答案,因爲很難在評論中包含內聯代碼 –

回答

0

如果您想在不存儲任何實際數據的情況下進行用戶身份驗證,則可以使用sessioncookies作爲最後的手段。會話數據可以被加密並存儲在會話cookie本身或一個輔助cookie中。

這將如何工作?

您可以創建一個端點,如api/v1/user/login,作爲處理用戶認證/登錄的UserResource方法。你可以這樣做是這樣的:

def override_urls(self): 
    return [ 
     url(r"^(?P<resource_name>%s)/login%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('user_login'), name="api_user_login"), 
    ] 

def user_login(self, request, **kwargs): 
    # Authentication process happens here. 
    return self.create_response(request, {}) 

對於上述工作,你必須輸入tastypie.utils.trailing_slashdjango.conf.urls.url。不幸的是,tastypie不支持任何輔助方法來更輕鬆地創建網址。

user_login方法,那麼您需要進行身份驗證通過POST通過對遠程端點憑據,並在request.session的用戶名和密碼的存儲與任何遠程身份驗證端點特定的數據一起。在RemoteAuthentication中,您可以檢查會話密鑰是否存在。

如果會話是本地文件系統中的數據,那麼內部的數據可以被認爲更安全一些。如果您決定將會話數據存儲在加密的cookie中,則必須爲每個會話密鑰存儲值和校驗和,可能存儲在單個cookie條目中,或單獨存儲。

由於用戶將以明文形式傳遞其憑據以登錄,因此您可以考慮通過SSL提供user_login視圖(請確保該cookie不是secure_only)。

+0

但我想在整個資源BasicAuthentication的原因是,我不想保持登錄。隨機請求將使用cURL或JQuery/Ajax資源的方法。每個請求都將使用用戶名和密碼進行,不一定每次都是一樣的。 –

+1

然後,您可以在自定義標頭中傳遞用戶名和密碼,即'X-MYAPP-ID'和'X-MYAPP-PASSWORD',並從'request.META'中的'RemoteAuthentication'中獲取這些值,並通過遠程驗證用戶服務 –