2017-07-22 36 views
0

到目前爲止,我正在使用漏勺驗證我的aiohttp應用程序中的數據。如何使用Pyramid的漏勺驗證應用程序邏輯?

我面臨的問題是我不知道如何做「深度」驗證。

考慮以下模式:

import colander 

class User(colander.MappingSchema): 
    username = colander.SchemaNode(colander.String()) 
    password = colander.SchemaNode(colander.String()) 
    confirmation = colander.SchemaNode(colander.String()) 

我兩者都做驗證輸入數據結構具有所有必要的字段有(約束最小爲清楚起見),但我還需要 檢查:

  • username尚未被其它用戶
  • passwordconfirmation是相同

所以在我的控制器,代碼如下所示的僞代碼:

def create_user(request): 
    user = await request.json() 
    schema = User() 
    # do schema validation 
    try: 
     user = schema.deserialize(user) 
    except colander.Invalid, exc: 
     response = dict(
      status='error', 
      errors=errors.asdict() 
     ) 
     return json_response(response) 
    else: 
     # check password and confirmation are the same 
     if user['password'] != user['confirmation']: 
      response = dict(
       status='error' 
       errors=dict(confirmation="doesn't match password") 
      ) 
      return json_response(response) 
     # check the user is not already used by another user 
     # we want usernames to be unique 
     if user_exists(user['user']): 
      response = dict(
       status='error', 
       errors=dict(username='Choose another username') 
      ) 
      return json_response(response) 

     return json_response(dict(status='ok')) 

基本上有有兩種驗證。是否有可能在單個漏斗模式中具有邏輯?這是一個很好的模式嗎?

回答

1

顯然這是一個味道的問題,但恕我直言,最好保持數據驗證與應用程序邏輯分開。

你還會碰到試圖確認用戶名是唯一的幾個問題:

  1. 漏勺將需要對您的申請如知識。訪問數據庫連接以檢查數據庫是否存在該用戶名。
  2. Colander(AFAIK)未針對asyncio編程進行設置,因此在檢查用戶是否存在時會遇到問題,例如async
  3. 您真的希望創建用戶爲ACID,因此使用相同的用戶名同時呼叫create_user無法創建具有相同用戶名的兩個用戶。

檢查密碼匹配是另一回事,它不需要關於世界其他地方的任何知識,並且應該相當瑣碎地用漏勺。我不擅長漏勺,但看起來你可以用deferred validator來檢查兩個密碼是否匹配。

你的代碼的一些其他注意事項:

  1. create_user應該是一個async方法
  2. 我不知道你的分貝什麼,而是從異步編程user_exists應該是異步太得到任何好處
  3. 用戶存在檢查應該包裝到ACID用戶創建中。例如。你應該使用postgres的on conflict或相當於捕獲一個重複的用戶,因爲你創建它們而不是檢查它們是否存在第一個
  4. 要正確地恢復和使測試更容易,你的視圖應該返回錯誤時正確的http響應代碼(目前你返回200所有州)。您應該使用201創建,400使用無效日期和409或用戶名衝突。
+0

Tx!這段代碼大多是僞代碼,它不是我正在運行的代碼。我有一個關於第三點的問題。如果我將所有查詢包含在一個事務中,它是否會提供與使用'on conflict'或捕獲重複用戶相同的功能? – amirouche

+0

該代碼是在線https://github.com/amirouche/socialite/blob/master/socialite/api.py#L54 – amirouche

+0

順便說一句我沒有使用漏勺,但traferet更容易寫IMO。 – amirouche