2015-05-09 71 views
2

我正在一個項目(不是任何合作項目,學術)我正在使用flask-login使用其危險和登錄管理器的麻煩。如何解決它的危險.BadTimeSignature簽名錯誤

我創建了一個註冊表單。當 我重新啓動服務器中輸入我的名字電子郵件地址和密碼,然後,我得到這個:

``` 
itsdangerous.BadTimeSignature 
BadTimeSignature: Signature 'GAMjfzQpbKlPraWesdT49W40pA8' does not match 
``` 

錯誤的流程是這樣的:

return render_template('index.html') 
    ctx.app.update_template_context(context) 
    context.update(func()) 
return dict(current_user=_get_user()) 
    current_app.login_manager._load_user() 
    return self._load_from_cookie(request.cookies[cookie_name]) 
user = self.token_callback(cookie) 
line 93, in load_token 
    data = login_serializer.loads(token, max_age=max_age) 
.unsign(s, max_age, return_timestamp=True) 
in unsign 
    date_signed=timestamp) 
BadTimeSignature: Signature 'GAMjfzQpbKlPraWesdT49W40pA8' does not match 

的問題的根源是在這裏的主要應用程序運行的文件:

line 93, in load_token 
    data = login_serializer.loads(token, max_age=max_age) 

@login_manager.token_loader 
def load_token(token): 
    max_age = app.config["REMEMBER_COOKIE_DURATION"].total_seconds() 

    #decrypt token 
    data = login_serializer.loads(token, max_age=max_age) 

    user = find-and-get-user-object(data) 
    if user: 
     if data[2] == users password: return user object 
    return None 

的app.config [ 「REMEMBER_COOKIE_DURATION」]被設定爲

app.config["REMEMBER_COOKIE_DURATION"] = some timedelta days 

其中時間增量是從DateTime導入的。

模型文件具有在SQL鍊金術模型中定義的用戶模型:

get_auth_token(self): 
     return login_serializer.dumps([str(self.id_), self.email, self.pwd]) 

登錄串行器是基於

Base=declarative_base() 

與類方法:

from itsdangerous import URLSafeTimedSerializer 
app.secret_key = gen_random_key() 
login_serializer = URLSafeTimedSerializer(app.secret_key) 

在不提交路由的登錄管理器正在工作。

我想知道的是如何load_token()函數行:

data = login_serializer.loads(token, max_age=max_age) 

影響從用戶模型生成的令牌,它爲什麼要在一個路由檢查匹配,說「/」或任何途徑任何隨機可以訪問的地方。

我是否需要設置權限限制以設置登錄管理器不檢查每條路徑?

正如我所瞭解的,正在生成另一個令牌,以便將會話cookie更安全地綁定到服務器端Cookie,因爲服務器端Cookie信息將與基於get_auth_token的get_auth_token進行比較,該get_auth_token需要一些用戶屬性併發出令牌的隨機安全字符串。

+1

你是說你每次服務器啓動時都會創建一個新的應用程序密鑰? –

+0

@MartijnPieters HoHoly s ***!這就是問題所在?是的,我不保存它!我應該現在把它保存在ENV中! – user2290820

+0

@MartijnPieters謝謝指出! – user2290820

回答

6

您在這裏創建一個新的祕密,每次:

from itsdangerous import URLSafeTimedSerializer 
app.secret_key = gen_random_key() 
login_serializer = URLSafeTimedSerializer(app.secret_key) 

不要那樣做。創建一個爲您的應用程序的祕密,並始終貫穿始終。您的密鑰是使用此服務器端祕密簽名的,然後當cookie從瀏覽器返回時,再次用於驗證內容未被更改。

如果您每次更改密碼,先前生成的cookie總是會失效,因爲它們不會匹配新密碼。

存儲您的應用程序配置的祕密。

+0

謝謝。這清除了我的概念 – user2290820