2014-01-22 28 views
0

我的應用在登錄時將用戶的文檔從數據庫加載到redis會話中。然後,它會對會話對象的請求進行幾乎所有的驗證。請求之外的會話,驗證和操作

The problem:修改請求/響應週期之外的正在進行的會話以更新驗證信息。

例如,如果用戶訂閱博客帖子類別,他們可以閱讀該類別中的帖子以及對該類別的貢獻。但是,如果該類別的主持人決定刪除它,那麼我不僅需要從磁盤上的數據庫中的用戶文檔刪除該類別,還需要刪除redis中的用戶會話。

據我所知,唯一可以做到這一點的方法是在數據庫的用戶文檔中保存對會話ID的引用,並在redis中查找相應的會話。

問題是,我不確定會話是否被設計爲在請求/響應循環之外進行修改,因爲我沒有真正看到任何人在我執行谷歌搜索時想要這樣做的相關主題。

回答

1

我不認爲存儲有關mongo會話的信息是一個好主意。如果用戶同時從兩臺設備登錄,會發生什麼情況?我想你會在這種情況下有兩個會話對象(否則,應該有一個機制來猜測給定用戶的會話,然後你就不會有當前的問題)。

我的建議是在redis中存儲由用戶啓動的會話集。當用戶登錄時,您將新的會話ID添加到SET,並將用戶ID作爲密鑰的一部分。當用戶註銷時,您從SET中刪除相應的條目。

當然,如果沒有用戶手動註銷會話(如果您有這種行爲),會話會過期。爲此,每次啓動新會話時,您都可以將SETEXP設置爲用戶設置。只要您的SETEXP時間比您的會話過期時間長一點,您就可以確定只要會話存在,會話就會存儲在您的SET中。

新版本的redis將具有Observe命令,這將使刪除會話從您的設置對象中刪除更容易。你只需要觀察會話對象的創建/刪除,並且你可以根據它來管理你的SET插入/刪除。在該命令正式執行之前,您必須堅持按時到期。

+0

因此,修改該用戶請求之外的用戶會話不會導致無法預料的問題? – paulkon

+0

當在服務器端完成時,用戶會話只是字段的集合,然後是通過包含會話ID的cookie識別會話的機制。只要您不更改會話密鑰或刪除應用程序其餘部分依賴的任何字段,就不應該在更改會話的值時出現任何問題。 –

+0

我正在考慮在特定用戶進行的所有會話之間形成應用程序端外鍵關係,以及存儲用戶會話對象的單個redis鍵/值,並且在任何時候訪問相同的ttl作爲會話密鑰/值(1天)。所以它會是:'sess1:123,sess2:123,sess3:123,user:123:{user json object}'。在應用程序端,我會查詢'user +':'+ _id(從用戶的mongo _id中借用),然後我將隨setex更新ttl以及任何更改。你認爲這會是一個好主意嗎? – paulkon