???????起因還是因?yàn)轵v飛學(xué)給我下發(fā)的任務(wù)战得,讓我把eladmin的持久層框架jpa換成我們熟悉的mybatis/mybatis plus,這可謂是一個(gè)比較龐大的工程梯澜,因?yàn)橐WCeladmin前端在接口不變的情況下可以直接登錄使用婿失,這就要求你要掌握整個(gè)eladmin源碼的運(yùn)行流程享幽。
???????就在第二天轉(zhuǎn)化security模塊中的獲取驗(yàn)證碼接口時(shí)睹限,發(fā)現(xiàn)了一個(gè)比較奇怪的情況譬猫,當(dāng)輸入驗(yàn)證碼結(jié)果為0的情況時(shí)讯檐,提示輸入驗(yàn)證碼錯(cuò)誤,例如:0+0染服、0x9等别洪。起初我以為我只是自己看錯(cuò)了,也沒在意柳刮,其他的驗(yàn)證碼結(jié)果可以通過是正確的挖垛,但是之后卻發(fā)現(xiàn)確實(shí)在結(jié)果為0的時(shí)候提示了驗(yàn)證碼輸入錯(cuò)誤,而其他結(jié)果輸入就顯示正確秉颗。
???????第一時(shí)間先是和小桑學(xué)長提出這個(gè)問題痢毒,經(jīng)排查后發(fā)現(xiàn)redis里存入的驗(yàn)證碼結(jié)果是“0.0”,是一個(gè)浮點(diǎn)型數(shù)據(jù)蚕甥,難怪前端輸入0會(huì)報(bào)錯(cuò)哪替,我刷新了幾次驗(yàn)證碼又找到一個(gè)結(jié)果為0的驗(yàn)證碼,這次輸入0.0就成功了梢灭,看來是驗(yàn)證碼放入redis的問題,那就是在獲取驗(yàn)證碼接口中出了問題蒸其。
???????eladmin引入的驗(yàn)證碼為:
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>
???????最新的版本1.6.2也是1年前的了敏释。eladmin中獲取驗(yàn)證碼的接口是在security模塊下的rest/AuthorizationController中的/code接口。eladmin默認(rèn)使用的是算數(shù)型驗(yàn)證碼摸袁,放入緩存中的值為captcha.text()钥顽,Captcha是驗(yàn)證碼類,text()方法是將驗(yàn)證碼的結(jié)果以字符形式輸出靠汁,那問題就出現(xiàn)在這里了蜂大,經(jīng)測試,當(dāng)驗(yàn)證碼類型為 arithmetic時(shí)且長度 >= 2 時(shí)蝶怔,captcha.text()的結(jié)果有幾率為浮點(diǎn)型奶浦,那么根本的問題其實(shí)不在于eladmin,而是easy-captcha的問題踢星,不過可以先治標(biāo)澳叉,解決方法就是對(duì)captcha.text()的結(jié)果以"."分割,取第一部分沐悦,這樣就可以把數(shù)據(jù)的小數(shù)部分去掉成洗,魯棒性也比較高。
String captchaValue = captcha.text();
if (captcha.getCharType() - 1 == LoginCodeEnum.arithmetic.ordinal() & captchaValue.contains(".")) {
captchaValue = captchaValue.split("\\.")[0];
}
???????修改之后便給github eladmin提了一個(gè)pr藏否,等待著管理員elunez的審核通過瓶殃,畢竟這是第一次給人家大的開源項(xiàng)目提pr,還是比較緊張的副签。
???????學(xué)長鼓勵(lì)我追尋根本原因遥椿,之后又把easy-captcha的源碼給拉了下來基矮,經(jīng)一段時(shí)間的排查定位到根本問題是在算數(shù)型驗(yàn)證碼抽象類中的問題,在ArithmeticCaptchaAbstract中一串代碼:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
try {
chars = String.valueOf(engine.eval(sb.toString().replaceAll("x", "*")));
} catch (ScriptException e) {
e.printStackTrace();
}
???????其中關(guān)鍵問題就是在engine.eval中修壕,這個(gè)方法可以計(jì)算出一個(gè)算數(shù)式的結(jié)果并輸出愈捅,但是返回值類型Object,而實(shí)際有一部分為整形慈鸠,一部分為浮點(diǎn)型表锻,而easy-captcha并未對(duì)其處理氢橙,而是直接轉(zhuǎn)成字符串,而text()方法輸出的就是這個(gè)。由于強(qiáng)轉(zhuǎn)也比較麻煩蛉幸,最后也是用了比較粗暴的辦法就是直接分割字符串——split("\.")[0];
???????順便也提了一個(gè)pr,但是這個(gè)可能審批過的概率不大闽坡,畢竟上次更新都是7個(gè)月之前的事了伶贰。而我給eladmin提的pr也是一天天過去,其中有看到比我提交的早的分支被關(guān)閉娃肿,我還是比較恐慌的咕缎。
???????之后小桑學(xué)長在測試部門的時(shí)候又發(fā)現(xiàn)了一個(gè)bug,但是eladmin官方在幾天前最新的一次分支就是這個(gè)bug的修復(fù)料扰,但是小桑學(xué)長說可以簡化寫法凭豪,我就根據(jù)小桑學(xué)長的寫法又提了個(gè)pr,不料這次過了一會(huì)就被關(guān)閉了晒杈,并不是沒被采納嫂伞,而是eladmin自己根據(jù)小桑學(xué)長的的方法改了代碼。
???????這個(gè)關(guān)了就關(guān)了吧拯钻,還剩一個(gè)pr帖努。終于,9天過后粪般,我的郵箱收到了一封郵件拼余,顯示 Merged #464 into master. 功夫不負(fù)有心人,提的pr總算是合進(jìn)去了亩歹。
???????最后還要感謝小桑學(xué)長的幫助姿搜。