作者Crow22312 (烏鴉)
看板PHP
標題Re: [請益] Laracel 5.5 登入以及搬遷問題
時間Wed May 22 03:41:20 2019
開頭聲明一下我對 laravel 不是那麼了解..
※ 引述《st1009 (前端攻城師)》之銘言:
: 各位大大日安
: 不才想請教一下Laravel的登入系統,
: 不才寫了段code如下:
: $email = '[email protected]';
: $password = 'user-password';
: dd(Auth::attempt(['email' => $email, 'password' => $password]));
: 但是我從Stack上撈到了一組hash碼如下
: $hash = '$2y$10$NhRNj6QF.Bo6ePSRsClYD.4zHFyoQr/WOdcESjIuRsluN1DvzqSHm';
: 我使用我的password並且DB裏面密碼是使用這組hash時,
: 可以登入php artisan make:auth造出來的登入頁面,
: 卻無法登入上面那段code,不知道出了甚麼問題...
: 懇請各位大大解惑。
這個會建議你先把 dd 拔掉換成簡單的 if / var_dump 之類的接上 exit
印出來看看到底跑了什麼東西出來. 因為不是很確定你的 function dd
做什麼的, 但有可能它的行為會不如你預期..
: 此外我使用bcrypt()時,每次結果都不一樣...不知道要怎存DB,相當困惑。
要怎麼存 DB 可能要看你用的 bcrypt 從哪來的了..
( PHP 有相似的功能, 但沒直接內建這個名字的 function )
bcrypt 是個基於 blowfish cipher 的 hashing function,
既然是 hashing 那就是單向不可逆的, 而且就會有 cost / salt 這些問題,
使用的 cost / salt 不一樣就會有不一樣的結果;
這些資訊也必須一併存在 database 裡面
所以說要怎麼存得看你怎麼產生的.
$2y$10$NhRNj6QF.Bo6ePSRsClYD.4zHFyoQr/WOdcESjIuRsluN1DvzqSHm
若是以前述的這個為例子, 那就是..
$2y$ -> blowfish 的前綴
10$ -> cost = 10
NhRNj6QF.Bo6ePSRsClYD. -> hashing salt
4zHFyoQr/WOdcESjIuRsluN1DvzqSHm -> hashed result
你可以試試看:
echo crypt('user-password', '$2y$10$NhRNj6QF.Bo6ePSRsClYD.');
結果就會是前述那段.
想知道更多可以參考:
https://en.wikipedia.org/wiki/Bcrypt
https://www.php.net/manual/en/function.password-hash.php
( PASSWORD_BCRYPT 那段 )
https://www.php.net/manual/en/function.crypt.php
( CRYPT_BLOWFISH 那段; 其實前一個 link 就會把你騙來這了 )
然後是說 $2y$10$NhRNj6QF.Bo6ePSRsClYD.4zHFyoQr/WOdcESjIuRsluN1DvzqSHm
這個就是一個存 database 的良好範例了, cost / salt 都存放一起是 ok 的.
不需要做額外的修飾以及混淆, 額外的動作對於安全性幫助不大
只會徒增日後維護的困難.
這也有很多額外的延伸閱讀, 但這邊就偷懶不放了 /o,o\
: 之所以要使用bcrypt()是因為本來有一個原有系統,使用者已經在上面註冊了帳密了,
: 希望搬到laravel之後,他們可以使用原來的帳密登入,
: 目前的想法是,
: 1.把登入密碼先用原來的md5加密
: 2.傳給laravel登入
: 為了完成這點,
: 1.我需要一個可以自定義的登入系統。
: 2.我需要把原有資料庫裡的MD5數據,用laravel的方式加密。
: 可是完全搞不懂Laravel的登入系統,太複雜了...
: 懇請各位大大幫忙<(_ _)>
: 另外我也看不太懂藏在hidden的csrf要如何作用...
看到 "md5加密" 這個首先必須要先釐清一點..
(password/) hashing 跟 encryption (加密) 是不同的東西:
前者是單向的, 後者才能取回原文;
前者目的是為了避免資料外流後使用者在其他網站的帳號也遭殃,
後者則是有各種可能的目的.
回到你的正題.. 就我的理解你現在構想的設計是:
1. 把舊資料庫的 md5 紀錄丟給 laravel 的 password hashing function
以後儲存在 laravel 的資料庫裡面.
2. 使用者來了以後先用 md5 hash 完以後才拿去 laravel 的登入 Auth:: 那個
驗證使用者的身分.
hmm.. 可以是可以啦, 但有點不太好:
1. 這樣子讓密碼被縮限於 md5 的 128 bits 長度,
亦即可以輕易的猜完所有組合然後登入任何使用者 ( 資料庫遭竊狀況 )
2. 日後若想再搬遷會增加維護上的困難 ( 今天你是 md5 還好,
這種作法若是遇上了有 cost/salt 的又 php 版本問題真的就會撞山 )
3. 你的這個前置的 md5 動作必須隨著日後 laravel 更新一起維護拔不掉
遇到 password hashing function 改變通常的作法是..
0. 預先把舊系統的帳號在新系統裡面註冊起來, 標註一個尚未搬遷的 flag
( 這個用來避免舊帳戶回鍋前就被新系統的其他人註冊造成衝突 )
1. 使用者經由新系統登入
2. 新系統登入失敗後由額外的 code 介入
( wordpress 直接有 hook 可以用, laraval 我不熟 Orz )
3. 檢查新系統裡面是否真的存在帳號
3n. 登入失敗 不做額外處理 (end)
4. 檢查帳號搬遷完畢 flag 是否已完成搬遷
4y. 已完成搬遷者 登入失敗 不做額外處理 (end)
5. 將帳號密碼拿去舊系統登入看看是否會成功
5n. 登入失敗 不做額外處理 (end)
6. 透過新系統的方式變更密碼, 將明文密碼交由新系統去儲存
並且標註為已完成搬遷 (登入成功)
亦即真正正確的密碼搬遷到新系統的資料庫是發生在你改好以後
使用者第一次回來成功登入你的網站的時候.
99. 超過一定時間或者一定比例使用者回鍋後關閉上述途徑
日後再回鍋的就人工接洽處理或者系統信變更密碼那套處理
( 一來是舊系統就算只有 user 這個 table 撐著也是種成本
二來是時間太久的說實話密碼的安全性也沒多少 不如重新驗證 )
這種做法的好處是:
- 比較不惱人 (使用者; 相較於強迫重發密碼變更信之類的方法而言)
- 不犧牲新系統的 hashing 所帶來的安全性強度
- 單純化資料與處理方式, 不會幾年後你要透過層層 hashing 才能登入
當然也是有缺點:
- 相當多額外的 code (對老闆來說沒差 A_A)
- 去舊系統驗證登入這段有時間差, 嚴格上來說算是一種安全性漏洞
( 輸入一組帳號明顯網頁反應時間比較慢就知道這組帳號存在且未回鍋 )
- 相當多額外的 code (沒錯 沒錯)
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.169.46.22
※ 文章網址: https://webptt.com/m.aspx?n=bbs/PHP/M.1558467687.A.8C7.html
※ 編輯: Crow22312 (118.169.46.22), 05/22/2019 03:45:32
※ 編輯: Crow22312 (118.169.46.22), 05/22/2019 03:46:46
1F:推 st1009: 真的很感謝您讓我學習了,您提的搬遷辦法感覺很棒,至於那 05/22 08:44
2F:→ st1009: 個相當多額外的 code嘛... 看完成時跟Deadline差多遠吧... 05/22 08:45
也不是真的全都自己想出來的啦 /o,o\
是之前搬遷過一個 md5/bcrypt 混成的到我也忘了用什麼 hashing 的去
所以還算有記憶.. 只不過就找不到之前是參考 stackoverflow 上的哪篇了
3F:推 st1009: 要改成可以抓MD5登入真不是普通難... 05/23 00:59
4F:推 st1009: 把HASH換成MD5,我辦的到,但要做到bcrypt和MD5都行真的太 05/23 01:11
5F:→ st1009: 難了...不知道有人可以教教我嘛QQ 05/23 01:11
6F:→ st1009: 而且如果可以最好是不要改核心,用覆寫的,難度又上升了.. 05/23 01:12
7F:推 st1009: 仔細想想,反正本來就是暫時性的,更新會被蓋掉就蓋掉,我 05/23 04:18
8F:→ st1009: 改kernel好了... 05/23 04:18
9F:推 st1009: shorturl.at/htJMR stackoverflow有解法~意外簡單... 05/23 15:26
link 看起來不通, 或許指的是這篇(?)
https://stackoverflow.com/a/36062706
更新資料庫中密碼的動作可以跟驗證拆開這還真是沒想到, 一拆開還真的清楚又簡潔
※ 編輯: Crow22312 (118.169.46.22), 05/24/2019 01:30:48
11F:→ st1009: 其實是這篇>///< 05/24 01:53
這篇直接把 1 2 5 6 都處理好了 真不錯
// This model use your second connection to the other database
這段如果我沒理解錯, 是連去現行 laravel 使用以外的其他 user table
那就要小心:
a. 拿到就密碼的壞人可以一直用舊密碼登入
( 甚至有可能因為使用的是 collision 所以真正帳號主人反而會變得無法登入.. )
b. 因為回鍋時間太慢被其他人註冊走相同帳號發生不可預期的問題
( 但都用 email 當帳號的話應該就不會? )
※ 編輯: Crow22312 (118.169.46.22), 05/24/2019 02:20:06
12F:推 st1009: $user->password = bcrypt($request->password); 05/24 02:53
13F:→ st1009: 其實他可以連其他,但我還是用同一個table,那段主要的意思 05/24 02:54
14F:→ st1009: 是,用的不是laravel自己的驗證過程(? 05/24 02:54
15F:→ st1009: 然後上面那行code可以更新密碼,所以不會舊帳一直登 05/24 02:55
16F:→ Crow22312: table 會更新就好 那就沒甚麼好擔心了 0-0/ 05/25 02:31
17F:推 st1009: 謝謝你 <3 05/25 07:45
18F:推 KKFN: dd是一個composer的套件,基本上等同 var_dump($var); die() 05/27 08:28
19F:→ KKFN: ; 05/27 08:28
20F:→ KKFN: 但是差別在於當輸出於網頁時,會帶HTML與Javascript 可以進 05/27 08:28
21F:→ KKFN: 行折疊。 05/27 08:28
22F:→ Crow22312: 原來如此.. 我們家太多東西土砲 套件認識很狹隘 Orz 06/05 10:58