摘要:設(shè)置驗(yàn)證碼任何人都可以在我們的博客下發(fā)布評(píng)論,所以我們需要避免非人類用戶來擾亂秩序。一個(gè)簡(jiǎn)單的防范方法是設(shè)置驗(yàn)證碼。然后我們修改表單來顯示驗(yàn)證碼,并把寫入隱藏的域里面。檢查驗(yàn)證碼功能是否完成了。
設(shè)置驗(yàn)證碼
任何人都可以在我們的博客下發(fā)布評(píng)論,所以我們需要避免非人類用戶來擾亂秩序。一個(gè)簡(jiǎn)單的防范方法是設(shè)置驗(yàn)證碼。
生成驗(yàn)證碼如何利用Play框架來生成驗(yàn)證碼?簡(jiǎn)單來說,我們需要增加一個(gè)action,不過讓它返回的是一個(gè)二進(jìn)制的對(duì)象而不是之前的HTML頁面。
因?yàn)镻lay是一個(gè)全棧式框架,我們?cè)噲D在框架內(nèi)部?jī)?nèi)置了Web應(yīng)用通常所需的東西;其中就包括生成驗(yàn)證碼。我們可以使用play.libs.Images來簡(jiǎn)單地生成驗(yàn)證碼,然后通過HTTP響應(yīng)返回它。
如常,我們先從一個(gè)原型開始。在Applicantion控制器中添加captcha action。
public static void captcha() { Images.Captcha captcha = Images.captcha(); renderBinary(captcha); }
注意我們可以直接傳遞captcha對(duì)象給renderBinary(),因?yàn)镮mages.Captcha類實(shí)現(xiàn)了java.io.InputStream。
請(qǐng)勿忘記導(dǎo)入play.lib.*
現(xiàn)在向/yabe/conf/routes添加新路由:
GET /captcha Application.captcha
然后打開http://localhost:9000/captcha看看效果。
每次刷新時(shí)應(yīng)該會(huì)產(chǎn)生隨機(jī)的文字
我們?cè)鯓庸芾頎顟B(tài)?目前為止事情順利,但是最復(fù)雜的部分就要來了。要想驗(yàn)證驗(yàn)證碼,我們需要保存驗(yàn)證碼圖片上的文字,然后跟提交的表單進(jìn)行比對(duì)。
當(dāng)然我們可以把文字存儲(chǔ)在用戶會(huì)話中,然后在驗(yàn)證時(shí)再提取出來。但這樣做有兩個(gè)問題:
首先,Play的會(huì)話是存儲(chǔ)在cookie里的。這樣解決了一些架構(gòu)上的問題,但是也引入一些麻煩。寫入到cookie的數(shù)據(jù)是簽了名的,這樣用戶就不能修改它;但是它并未加密。如果我們把驗(yàn)證碼的內(nèi)容寫入cookie,每個(gè)人都可以讀到它 —— 然后破解它。
其次,不要忘了Play是一個(gè)無狀態(tài)的框架。我們想要在無狀態(tài)的情況下管理事務(wù)。假如一個(gè)用戶同時(shí)打開兩個(gè)不同的博客頁面,生成了不同的驗(yàn)證碼,我們就需要跟蹤處理對(duì)應(yīng)的驗(yàn)證碼。
所以要想解決問題,我們需要兩樣?xùn)|西。我們得在服務(wù)器存儲(chǔ)驗(yàn)證碼的密鑰。因?yàn)樗且粋€(gè)臨時(shí)數(shù)據(jù),我們可以存儲(chǔ)在Play緩存(Cache)中。此外,這樣做還可以增加安全性,因?yàn)榇鎯?chǔ)在緩存中的數(shù)據(jù)的生命期是有限的(比如10分鐘)。然后我們還需要生成獨(dú)一無二的ID。這個(gè)ID將添加到每個(gè)表單的隱藏域中,對(duì)應(yīng)著一個(gè)生成的驗(yàn)證碼。
下面讓我們來解決這個(gè)問題吧。
修改captcha action成這樣:
public static void captcha(String id) { Images.Captcha captcha = Images.captcha(); String code = captcha.getText("#E4EAFD"); Cache.set(id, code, "10mn"); renderBinary(captcha); }
注意getText()方法接受任意顏色作為參數(shù)。它需要輸入的顏色來畫文本。
添加驗(yàn)證碼到評(píng)論框請(qǐng)勿忘記導(dǎo)入play.cache.*。
現(xiàn)在,在顯示一個(gè)評(píng)論框之前我們先生成一個(gè)獨(dú)一無二的ID。然后我們修改HTML表單來顯示驗(yàn)證碼,并把ID寫入隱藏的域里面。
讓我們重寫Application.show action:
public static void show(Long id) { Post post = Post.findById(id); String randomID = Codec.UUID(); render(post, randomID); }
以及/yable/app/views/Application/show.html模板中的表單:
…
…
好棒,現(xiàn)在評(píng)論框里能看到驗(yàn)證碼了。
驗(yàn)證驗(yàn)證碼現(xiàn)在來驗(yàn)證驗(yàn)證碼吧。我們添加了randomID作為隱藏域?qū)Π??那就?b>postComment里面把它提取出來,然后取出緩存中對(duì)應(yīng)的編碼,最后跟提交的輸入進(jìn)行比對(duì)。
這一點(diǎn)都不難。讓我們來修改postComment方法。
public static void postComment( Long postId, @Required(message="Author is required") String author, @Required(message="A message is required") String content, @Required(message="Please type the code") String code, String randomID) { Post post = Post.findById(postId); validation.equals( code, Cache.get(randomID) ).message("Invalid code. Please type it again"); if(validation.hasErrors()) { render("Application/show.html", post, randomID); } post.addComment(author, content); flash.success("Thanks for posting %s", author); Cache.delete(randomID); show(postId); }
因?yàn)楝F(xiàn)在有不同的錯(cuò)誤信息,而我們只想顯示第一條信息,所以修改show.html模板中顯示錯(cuò)誤的部分:
.. #{ifErrors}${errors[0]}
#{/ifErrors} …
對(duì)于一個(gè)更加復(fù)雜的表單,錯(cuò)誤信息不應(yīng)該這樣管理,而應(yīng)該集中到一個(gè)訊息文件中,并且每個(gè)錯(cuò)誤都應(yīng)該在對(duì)應(yīng)的區(qū)域內(nèi)顯示。
檢查驗(yàn)證碼功能是否完成了。
耶!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/64100.html
摘要:完成應(yīng)用測(cè)試我們已經(jīng)完成了我們想要?jiǎng)?chuàng)建的博客引擎。當(dāng)然我們已經(jīng)完成了測(cè)試所有模型層的功能。評(píng)估代碼覆蓋率當(dāng)然我們還沒有完成應(yīng)用所需的所有測(cè)試用例。如你所見,我們遠(yuǎn)遠(yuǎn)沒有完成對(duì)應(yīng)用的全面測(cè)試。 完成應(yīng)用測(cè)試 我們已經(jīng)完成了我們想要?jiǎng)?chuàng)建的博客引擎。不過這個(gè)項(xiàng)目尚未完全結(jié)束。為了保證代碼的質(zhì)量,我們需要添加更多的測(cè)試。 當(dāng)然我們已經(jīng)完成了測(cè)試所有模型層的功能。所以博客引擎的核心功能已經(jīng)被...
摘要:確保你的文本編輯器已經(jīng)做了相應(yīng)的配置。第一個(gè),會(huì)自動(dòng)監(jiān)測(cè)源代碼的改變并在運(yùn)行時(shí)自動(dòng)重載。檢查下面的一行是否出現(xiàn)在應(yīng)用日志中使用版本控制系統(tǒng)來追蹤變化當(dāng)你開發(fā)一個(gè)項(xiàng)目時(shí),最好使用版本控制系統(tǒng)來存儲(chǔ)你的源代碼。 Play是一個(gè)Java Web敏捷開發(fā)的框架http://www.playframework.com/documentation/1.2.7/home 之所以要翻譯這個(gè)教程,是因...
摘要:瀏覽和提交評(píng)論博客主頁現(xiàn)在已經(jīng)完成,接下來要完成博客正文頁面。整個(gè)頁面將展示當(dāng)前文章的所有評(píng)論,還包括一個(gè)用于提交新的評(píng)論的表單。刷新瀏覽器,檢查這次是否使用了正確的。給模板添加表單在后面試下提交新的評(píng)論。 瀏覽和提交評(píng)論 博客主頁現(xiàn)在已經(jīng)完成,接下來要完成博客正文頁面。整個(gè)頁面將展示當(dāng)前文章的所有評(píng)論,還包括一個(gè)用于提交新的評(píng)論的表單。 創(chuàng)建show action 要顯示文章內(nèi)...
摘要:添加驗(yàn)證既然我們有一個(gè)管理面板,自然需要進(jìn)行驗(yàn)證。自定義驗(yàn)證過程你可以用應(yīng)用提供的實(shí)例來自定義驗(yàn)證過程。通過繼承自該類,我們可以指定驗(yàn)證用戶的方式。這個(gè)將給每個(gè)作者發(fā)布自己的文章的權(quán)限?,F(xiàn)在在添加到控制器的鏈接接下來是創(chuàng)建模板。 添加驗(yàn)證 既然我們有一個(gè)管理面板,自然需要進(jìn)行驗(yàn)證。幸運(yùn)的是,Play已經(jīng)提供了一個(gè)叫做Secure的模塊來幫助我們。 啟動(dòng)Secure模塊 在yabe/co...
摘要:通過來實(shí)現(xiàn)一個(gè)基本的管理面板目前,我們還沒法使用博客的來寫新的文章,或修改評(píng)論。提供了一個(gè)即開即用的模塊,可以快速生成一個(gè)基本的管理面板。這是因?yàn)槟J(rèn)是以的輸出來得到一個(gè)模型對(duì)象的表示。在本教程的最后一章,你會(huì)學(xué)到關(guān)于本地化信息的更多東西。 通過CRUD來實(shí)現(xiàn)一個(gè)基本的管理面板 目前,我們還沒法使用博客的UI來寫新的文章,或修改評(píng)論。Play提供了一個(gè)即開即用的CRUD模塊,可以快速...
閱讀 2681·2023-04-25 17:33
閱讀 717·2021-11-23 09:51
閱讀 3037·2021-07-30 15:32
閱讀 1498·2019-08-29 18:40
閱讀 2027·2019-08-28 18:19
閱讀 1528·2019-08-26 13:48
閱讀 2314·2019-08-23 16:48
閱讀 2356·2019-08-23 15:56