2012-12-04 126 views
2

我有一個存儲登錄數據的Mysql數據庫。密碼和salt被保存爲sha512哈希值。現在,如果要更改密碼列中的值,我想實現一個條件,即鹽必須改變,否則mysql命令無效。現在Mysql:更新第一列後可能強制更新第二列?

CREATE TABLE loginData(
id int UNSIGNED SERIAL DEFAULT VALUE, 
email varchar(64) NOT NULL, 
password binary(64) NOT NULL, 
salt binary(64) NOT NULL, 
PRIMARY KEY(id)) 
ENGINE=InnoDB; 

,我想的是一樣的東西外鍵的完整性約束,但顯然我不應該連接的口令和鹽列外鍵。有什麼辦法來防止更新密碼列 - 這樣一個新的鹽必須給予 - 在 Mysql的的一面?僅在訪問代碼方面防止它感覺不完整。你都不可能做到這一點

+0

SQL具有CHECK約束這樣的事情。但MySQL不支持它們。 (它解析,但不強制)考慮一個不同的RDBMS,或者通過可以強制執行此限制的存儲過程強制所有調用。 –

回答

0

一種方法是不實際的密碼更改更新您的登錄記錄,但將新記錄。您需要更改模式以添加名爲active的tinyint字段名稱或類似名稱,以存儲指示哪個是活動登錄名的標誌。

然後,您可以添加電子郵件/鹽和電子郵件/密碼的唯一索引,以強制這些組合的唯一性,這意味着你永遠不會有相同的電子郵件與輸入相同的鹽,也永遠不會輸入相同的電子郵件/密碼組合。任何具有相同電子郵件/鹽或電子郵件/密碼的插入都會失敗。如果您不需要密碼唯一性(您可以顯然不添加電子郵件/密碼唯一索引)。

當你查找登錄到實際執行的認證檢查,你就只需要添加WHERE active = 1到查詢過濾器。

你可能也想包裝插入新鹽&密碼記錄和事務中更新的舊行active = 0,這樣無論是對整個交易成功或失敗,從而防止,用戶沒有卡住的情況下操作登錄。

+0

有趣,但我認爲「邪惡」的管理員(或腳本在那個)仍然可以先走一步,更新密碼(不更新的鹽),如果他決定無視插入新變種的「達成共識」的過程。另外,我想你會介紹一下整個世界可能遇到的雙重入口問題? – Hendrik

0

除非你有多個系統訪問數據庫的,我不會說防止它僅在訪問代碼是不完整的。您可以防止管理員手動更新數據,因爲他們不會在表上給予適當的寫權限。

但是如果你必須執行此在MySQL中,你可以考慮增加一個觸發器(代碼時更新記錄後運行),但如果鹽來自於你的應用程序,這可能是不可行的。那麼最好的選擇是隻通過一個存儲過程(駐留在數據庫中的代碼)提供對錶的訪問,這會強制表的完整性。

http://dev.mysql.com/doc/refman/5.6/en/stored-programs-views.html

+0

現在的情況是我要設置系統,但可能不管理它,所以我試圖儘可能地防止它。我會嘗試在更新列上添加一個觸發器,但是你說得對,鹽確實來自應用程序,所以有人手動更改密碼列的情況可能太不可能實際打擾。 – Hendrik

相關問題