2010-07-21 53 views
6

我有一個cherrypy應用程序,並且我想啓動一些視圖,只允許某些用戶查看它們,並將其他人發送到需要授權的頁面。編寫一個CherryPy裝飾器進行授權

有沒有一種方法可以用自定義裝飾器做到這一點?我認爲這將是最優雅的選擇。

這裏是什麼,我想做一個簡單的例子:

class MyApp: 
    @authorization_required 
    def view_page1(self,appID): 
     ... do some stuff ... 
     return html 

def authorization_required(func): 
    #what do I put here? 

也可以在調用時,一個裝飾的AUTHORIZATION_REQUIRED函數接受像allow_group1,allow_group2參數?或者我需要爲每個組單獨裝飾器?

+0

所有這些都是可能的,但是您使用的是什麼樣的身份驗證系統。或計劃使用? CherryPy有幾個身份驗證方法:http://www.cherrypy.org/wiki/BuiltinTools – Wolph 2010-07-21 19:12:50

+0

我不認爲我想使用任何內置的東西。我們有一些我需要檢查的自定義數據存儲庫,等等。 – Greg 2010-07-21 19:14:03

回答

4

好了,在這種情況下你的裝飾會是這個樣子:

# without any parameters 
def authentication_required(f): 
    @functools.wraps(f) 
    def _authentication_required(*args, **kwargs): 
     # Do you login stuff here 
     return f(*args, **kwargs) 
    return _authentication_required 

# With parameters 
def authentication_required(*allowed_groups): 
    def _authentication_required(f): 
     @functools.wraps(f) 
     def __authentication_required(*args, **kwargs): 
      # Do you login stuff here 
      return f(*args, **kwargs) 
     return __authentication_required 
    return _authentication_required 
+2

@ functools.wraps做什麼?這是建在櫻桃? – Greg 2010-07-21 19:21:20

+0

另外,我想我只有當登錄的東西成功時才返回f(* args,** kwargs)?另一方面,如果用戶沒有被授權,我會打電話給cherry.redirect而不是返回嗎? – Greg 2010-07-21 19:23:50

+0

是的,正確的。 而'functools.wraps'是一個處理函數名稱,文檔和其他數據寫入裝飾器時自動複製的方法。這樣,如果您對裝飾方法執行「幫助(方法)」,您仍然可以獲得原始文檔。 – Wolph 2010-07-21 19:37:25

13

你真的不希望編寫自定義裝飾器的CherryPy。相反,你要編寫一個新的工具:

def myauth(allowed_groups=None, debug=False): 
    # Do your auth here... 
    authlib.auth(...) 
cherrypy.tools.myauth = cherrypy.Tool("on_start_resource", myauth) 

更多的討論參見http://docs.cherrypy.org/en/latest/extend.html#tools。這個擁有超過編寫定製的裝飾幾個好處:

  1. 你得到裝飾免費從工具:@cherrypy.tools.myauth(allowed_groups=['me']),並已經知道如何不會破壞對同一功能cherrypy.exposed。
  2. 您可以通過處理程序(使用裝飾器),每個控制器樹(通過_cp_config)或每個URI樹(在配置文件或字符串中)應用工具。你甚至可以混合它們並通過裝飾器提供基本功能,然後在配置文件中覆蓋它們的行爲。
  3. 如果一個配置文件關閉了你的功能,你就不會爲調用裝飾函數來判斷它是否關閉而犧牲性能。
  4. 你會記得像所有的內置工具一樣添加一個'debug'參數。 ;)
  5. 通過選擇不同的「點」,您的功能可以比自定義裝飾器更早(或更晚,如果這是您需要的)運行。
  6. 如果需要,您的功能可以在多個鉤點運行。
+0

我不確定這是否適用於我,因爲這段代碼使用了RoutesDispatcher(而不是?)這個expose裝飾器。我不確定爲什麼這樣做。 – Greg 2010-07-21 23:08:48

+0

您使用哪個調度程序並不是一個真正的問題:任何值得使用它的調度程序(包括路徑一)都可以使用工具。 這個expose裝飾器只不過是設置了'method.exposed = True'。同樣,這對所有調度員都是必需的,並且不論工具是否工作。從馬的嘴裏拿出來:工具是CherryPy做到這一點的方法。 – fumanchu 2010-07-23 06:14:26

+0

提供的代碼片段在哪裏去? – 2016-12-05 05:07:28